From 69df50619a7ba59c6796deae6e8ec18ca9907198 Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Mon, 5 Jan 2026 18:34:19 +0100 Subject: [PATCH] DB/Dependency * remove unmaintained DbSimple * add package db/dibi as substitute db abstraction --- README.md | 2 +- composer.json | 2 +- composer.lock | 139 +- endpoints/account/account.php | 16 +- endpoints/account/activate.php | 6 +- endpoints/account/confirm-delete.php | 34 +- endpoints/account/confirm-email-address.php | 4 +- endpoints/account/confirm-password.php | 4 +- endpoints/account/delete-icon.php | 6 +- endpoints/account/delete.php | 4 +- endpoints/account/exclude.php | 21 +- endpoints/account/favorites.php | 4 +- endpoints/account/forgot-password.php | 6 +- endpoints/account/forgot-username.php | 6 +- endpoints/account/forum-avatar.php | 14 +- endpoints/account/premium-border.php | 4 +- endpoints/account/rename-icon.php | 2 +- endpoints/account/resend.php | 6 +- endpoints/account/reset-password.php | 6 +- endpoints/account/revert-email-address.php | 4 +- endpoints/account/signin.php | 8 +- endpoints/account/signout.php | 4 +- endpoints/account/signup.php | 14 +- .../account/update-community-settings.php | 2 +- endpoints/account/update-email.php | 8 +- endpoints/account/update-general-settings.php | 6 +- endpoints/account/update-password.php | 8 +- endpoints/account/update-username.php | 6 +- endpoints/account/weightscales.php | 26 +- endpoints/achievement/achievement.php | 18 +- endpoints/achievements/achievements.php | 2 +- endpoints/admin/announcements.php | 4 +- endpoints/admin/comment.php | 4 +- endpoints/admin/guide.php | 10 +- endpoints/admin/guides.php | 2 +- endpoints/admin/screenshots.php | 2 +- endpoints/admin/screenshots_approve.php | 6 +- endpoints/admin/screenshots_delete.php | 12 +- endpoints/admin/screenshots_editalt.php | 2 +- endpoints/admin/screenshots_manage.php | 2 +- endpoints/admin/screenshots_relocate.php | 10 +- endpoints/admin/screenshots_sticky.php | 10 +- endpoints/admin/spawn-override.php | 12 +- endpoints/admin/videos.php | 2 +- endpoints/admin/videos_approve.php | 6 +- endpoints/admin/videos_delete.php | 10 +- endpoints/admin/videos_edittitle.php | 2 +- endpoints/admin/videos_manage.php | 2 +- endpoints/admin/videos_order.php | 4 +- endpoints/admin/videos_relocate.php | 10 +- endpoints/admin/videos_sticky.php | 10 +- endpoints/admin/weight-presets.php | 4 +- endpoints/admin/weight-presets_save.php | 6 +- endpoints/arena-team/arena-team.php | 9 +- endpoints/arena-team/resync.php | 4 +- endpoints/class/class.php | 12 +- endpoints/comment/add-reply.php | 4 +- endpoints/comment/add.php | 8 +- endpoints/comment/delete-reply.php | 15 +- endpoints/comment/delete.php | 19 +- endpoints/comment/detach-reply.php | 2 +- endpoints/comment/downvote-reply.php | 14 +- endpoints/comment/edit-reply.php | 9 +- endpoints/comment/edit.php | 4 +- endpoints/comment/flag-reply.php | 4 +- endpoints/comment/out-of-date.php | 6 +- endpoints/comment/rating.php | 2 +- endpoints/comment/sticky.php | 4 +- endpoints/comment/undelete.php | 17 +- endpoints/comment/upvote-reply.php | 14 +- endpoints/comment/vote.php | 6 +- endpoints/cookie/cookie.php | 4 +- endpoints/currency/currency.php | 6 +- endpoints/emote/emote.php | 9 +- endpoints/enchantment/enchantment.php | 26 +- endpoints/event/event.php | 18 +- endpoints/faction/faction.php | 32 +- endpoints/factions/factions.php | 4 +- endpoints/go-to-comment/go-to-comment.php | 2 +- endpoints/go-to-reply/go-to-reply.php | 2 +- endpoints/guide/changelog.php | 2 +- endpoints/guide/edit.php | 18 +- endpoints/guide/guide.php | 6 +- endpoints/guide/guide_power.php | 2 +- endpoints/guide/vote.php | 8 +- endpoints/guides/guides.php | 2 +- endpoints/guild/guild.php | 11 +- endpoints/guild/resync.php | 4 +- endpoints/home/home.php | 10 +- endpoints/icon/get-id-from-name.php | 2 +- endpoints/item/item.php | 38 +- endpoints/item/item_xml.php | 8 +- endpoints/items/items.php | 2 +- endpoints/mail/mail.php | 14 +- endpoints/most-comments/most-comments.php | 4 +- endpoints/most-comments/most-comments_rss.php | 4 +- endpoints/npc/npc.php | 80 +- endpoints/object/object.php | 48 +- endpoints/pet/pet.php | 10 +- endpoints/profile/avatar.php | 2 +- endpoints/profile/delete.php | 10 +- endpoints/profile/link.php | 6 +- endpoints/profile/load.php | 32 +- endpoints/profile/pin.php | 6 +- endpoints/profile/private.php | 6 +- endpoints/profile/profile.php | 19 +- endpoints/profile/profile_power.php | 2 +- endpoints/profile/public.php | 6 +- endpoints/profile/resync.php | 2 +- endpoints/profile/save.php | 16 +- endpoints/profile/status.php | 4 +- endpoints/profile/unlink.php | 4 +- endpoints/profile/unpin.php | 4 +- endpoints/profiles/profiles.php | 2 +- endpoints/quest/quest.php | 46 +- endpoints/race/race.php | 10 +- endpoints/reputation/reputation.php | 2 +- endpoints/screenshot/complete.php | 4 +- endpoints/signature/delete.php | 2 +- endpoints/signature/signature.php | 2 +- endpoints/skill/skill.php | 25 +- endpoints/sound/sound.php | 73 +- endpoints/spell/spell.php | 216 +-- endpoints/spells/spells.php | 40 +- endpoints/title/title.php | 10 +- endpoints/top-users/top-users.php | 20 +- endpoints/upload/image-complete.php | 2 +- endpoints/upload/image-crop.php | 4 +- endpoints/user/user.php | 12 +- endpoints/video/complete.php | 6 +- endpoints/zone/zone.php | 52 +- endpoints/zones/zones.php | 8 +- includes/cfg.class.php | 22 +- .../Conditions/Conditions.class.php | 42 +- includes/components/SmartAI/SmartAI.class.php | 88 +- .../components/SmartAI/SmartAction.class.php | 24 +- .../components/SmartAI/SmartEvent.class.php | 14 +- .../components/communitycontent.class.php | 203 ++- includes/components/dbtypelist.class.php | 321 ++-- includes/components/filter.class.php | 10 +- includes/components/guidemgr.class.php | 2 +- includes/components/profiler.class.php | 311 ++-- includes/components/report.class.php | 30 +- .../response/baseresponse.class.php | 12 +- .../response/templateresponse.class.php | 20 +- includes/components/screenshotmgr.class.php | 40 +- includes/components/search.class.php | 14 +- includes/components/videomgr.class.php | 33 +- includes/database.class.php | 181 --- includes/database.php | 332 ++++ includes/dbtypes/achievement.class.php | 18 +- includes/dbtypes/areatrigger.class.php | 8 +- includes/dbtypes/arenateam.class.php | 71 +- includes/dbtypes/charclass.class.php | 6 +- includes/dbtypes/charrace.class.php | 8 +- includes/dbtypes/creature.class.php | 62 +- includes/dbtypes/currency.class.php | 6 +- includes/dbtypes/emote.class.php | 6 +- includes/dbtypes/enchantment.class.php | 10 +- includes/dbtypes/faction.class.php | 8 +- includes/dbtypes/gameobject.class.php | 34 +- includes/dbtypes/guide.class.php | 23 +- includes/dbtypes/guild.class.php | 32 +- includes/dbtypes/icon.class.php | 42 +- includes/dbtypes/item.class.php | 242 +-- includes/dbtypes/itemset.class.php | 8 +- includes/dbtypes/mail.class.php | 6 +- includes/dbtypes/pet.class.php | 6 +- includes/dbtypes/profile.class.php | 112 +- includes/dbtypes/quest.class.php | 70 +- includes/dbtypes/skill.class.php | 6 +- includes/dbtypes/sound.class.php | 8 +- includes/dbtypes/spell.class.php | 78 +- includes/dbtypes/title.class.php | 8 +- includes/dbtypes/user.class.php | 6 +- includes/dbtypes/worldevent.class.php | 14 +- includes/dbtypes/zone.class.php | 4 +- includes/defines.php | 4 +- includes/game/chrstatistics.php | 2 +- includes/game/loot/lootbycontainer.class.php | 13 +- includes/game/loot/lootbyitem.class.php | 51 +- includes/game/misc.php | 29 +- includes/game/worldposition.class.php | 36 +- includes/kernel.php | 30 +- includes/libs/DbSimple/CacherImpl.php | 45 - includes/libs/DbSimple/Connect.php | 261 --- includes/libs/DbSimple/Database.php | 1406 ----------------- includes/libs/DbSimple/Generic.php | 193 --- includes/libs/DbSimple/Mysqli.php | 245 --- includes/libs/DbSimple/Zend/Cache.php | 250 --- .../DbSimple/Zend/Cache/Backend/Interface.php | 99 -- includes/type.class.php | 2 +- includes/user.class.php | 108 +- includes/utilities.php | 47 +- localization/lang.class.php | 6 +- prQueue | 18 +- setup/tools/CLISetup.class.php | 2 +- setup/tools/clisetup/account.us.php | 14 +- setup/tools/clisetup/datagen.us.php | 8 + setup/tools/clisetup/dbconfig.us.php | 14 +- setup/tools/clisetup/filegen.us.php | 8 + setup/tools/clisetup/sync.us.php | 4 +- setup/tools/clisetup/update.us.php | 8 +- setup/tools/dbc.class.php | 8 +- setup/tools/filegen/enchants.ss.php | 14 +- setup/tools/filegen/gems.ss.php | 10 +- setup/tools/filegen/glyphs.ss.php | 14 +- setup/tools/filegen/img-maps.ss.php | 6 +- setup/tools/filegen/img-talentcalc.ss.php | 2 +- setup/tools/filegen/itemscaling.ss.php | 8 +- setup/tools/filegen/itemsets.ss.php | 2 +- setup/tools/filegen/pets.ss.php | 14 +- setup/tools/filegen/profiler.ss.php | 14 +- setup/tools/filegen/simpleimg.ss.php | 2 +- setup/tools/filegen/soundfiles.ss.php | 4 +- setup/tools/filegen/statistics.ss.php | 22 +- setup/tools/filegen/talentcalc.ss.php | 12 +- setup/tools/filegen/talenticons.ss.php | 8 +- setup/tools/filegen/weightpresets.ss.php | 4 +- setup/tools/setupScript.class.php | 10 +- setup/tools/sqlgen/achievement.ss.php | 28 +- setup/tools/sqlgen/areatrigger.ss.php | 24 +- setup/tools/sqlgen/classes.ss.php | 22 +- setup/tools/sqlgen/creature.ss.php | 35 +- setup/tools/sqlgen/currencies.ss.php | 22 +- setup/tools/sqlgen/declinedword.ss.php | 10 +- setup/tools/sqlgen/emotes.ss.php | 26 +- setup/tools/sqlgen/events.ss.php | 10 +- setup/tools/sqlgen/factions.ss.php | 50 +- setup/tools/sqlgen/glyphproperties.ss.php | 8 +- setup/tools/sqlgen/holidays.ss.php | 12 +- setup/tools/sqlgen/icons.ss.php | 24 +- setup/tools/sqlgen/itemenchantment.ss.php | 16 +- setup/tools/sqlgen/itemrandomenchant.ss.php | 8 +- setup/tools/sqlgen/items.ss.php | 87 +- setup/tools/sqlgen/itemset.ss.php | 16 +- setup/tools/sqlgen/itemstats.ss.php | 32 +- setup/tools/sqlgen/mailtemplate.ss.php | 13 +- setup/tools/sqlgen/objects.ss.php | 21 +- setup/tools/sqlgen/pet.ss.php | 30 +- setup/tools/sqlgen/quests.ss.php | 63 +- setup/tools/sqlgen/questsstartend.ss.php | 10 +- setup/tools/sqlgen/races.ss.php | 14 +- setup/tools/sqlgen/shapeshiftforms.ss.php | 8 +- setup/tools/sqlgen/skillline.ss.php | 32 +- setup/tools/sqlgen/sounds.ss.php | 83 +- setup/tools/sqlgen/source.ss.php | 252 +-- setup/tools/sqlgen/spawns.ss.php | 114 +- setup/tools/sqlgen/spell.ss.php | 214 +-- setup/tools/sqlgen/spelldifficulty.ss.php | 44 +- setup/tools/sqlgen/talents.ss.php | 14 +- setup/tools/sqlgen/taxi.ss.php | 27 +- setup/tools/sqlgen/titles.ss.php | 40 +- setup/tools/sqlgen/zones.ss.php | 25 +- 254 files changed, 3234 insertions(+), 5566 deletions(-) delete mode 100644 includes/database.class.php create mode 100644 includes/database.php delete mode 100644 includes/libs/DbSimple/CacherImpl.php delete mode 100644 includes/libs/DbSimple/Connect.php delete mode 100644 includes/libs/DbSimple/Database.php delete mode 100644 includes/libs/DbSimple/Generic.php delete mode 100644 includes/libs/DbSimple/Mysqli.php delete mode 100644 includes/libs/DbSimple/Zend/Cache.php delete mode 100644 includes/libs/DbSimple/Zend/Cache/Backend/Interface.php diff --git a/README.md b/README.md index 34c6fa94..4578348a 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ audio processing may require [lame](https://sourceforge.net/projects/lame/files/ #### 2. Prepare the database Ensure that the account you are going to use has **full** access on the database AoWoW is going to occupy and ideally only **read** access on the world database you are going to reference. -Import files 01 - 03 from `setup/sql/` in order into the AoWoW database `mysql -p {your-db-here} < setup/sql/01-db_structure.sql`, etc. +Import files 01 - 03 from `setup/sql/` in order into the AoWoW database `mysql --default-character-set=utf8 -p {your-db-here} < setup/sql/01-db_structure.sql`, etc. **Optional**: If you are using MySQL ≥ 8.4.0 and want to support fulltext search for locale zhCN, additionally import `setup/sql/04-db_optional_mysql_only.sql`. Enables this in settings after AoWoW has been set up. diff --git a/composer.json b/composer.json index df92bbb7..fc43b9aa 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ "vendor-dir": "includes/libs" }, "require": { + "dibi/dibi": "^5.1", "php": "8.2 - 8.4", "ext-mbstring": "*", "ext-simplexml": "*", @@ -23,7 +24,6 @@ "ext-intl": "*" }, "require-dev": { - "dibi/dibi": "^5.1", "jfcherng/php-diff": "6.16", "triggerhappy/mpq": "dev-master" } diff --git a/composer.lock b/composer.lock index 1368563e..8d9a0b87 100644 --- a/composer.lock +++ b/composer.lock @@ -4,75 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8b4b9c139ad31fc7b659f11676582cb2", - "packages": [], - "packages-dev": [ - { - "name": "chdemko/sorted-collections", - "version": "1.0.10", - "source": { - "type": "git", - "url": "https://github.com/chdemko/php-sorted-collections.git", - "reference": "d9cf7021e6fda1eb68b9f35caf99215327f6db76" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chdemko/php-sorted-collections/zipball/d9cf7021e6fda1eb68b9f35caf99215327f6db76", - "reference": "d9cf7021e6fda1eb68b9f35caf99215327f6db76", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.7", - "phpbench/phpbench": "^1.3", - "phpunit/phpunit": "^11.3", - "squizlabs/php_codesniffer": "^3.10" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "chdemko\\SortedCollection\\": "src/SortedCollection" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Christophe Demko", - "email": "chdemko@gmail.com", - "homepage": "https://chdemko.pagelab.univ-lr.fr/", - "role": "Developer" - } - ], - "description": "Sorted Collections for PHP >= 8.1", - "homepage": "https://php-sorted-collections.readthedocs.io/en/latest/?badge=latest", - "keywords": [ - "avl", - "collection", - "iterator", - "map", - "ordered", - "set", - "sorted", - "tree", - "treemap", - "treeset" - ], - "support": { - "issues": "https://github.com/chdemko/php-sorted-collections/issues", - "source": "https://github.com/chdemko/php-sorted-collections/tree/1.0.10" - }, - "time": "2024-08-04T14:31:40+00:00" - }, + "content-hash": "25b289a987a7600746f0fd1f2491864b", + "packages": [ { "name": "dibi/dibi", "version": "v5.1.0", @@ -146,6 +79,74 @@ "source": "https://github.com/dg/dibi/tree/v5.1.0" }, "time": "2025-08-06T22:26:19+00:00" + } + ], + "packages-dev": [ + { + "name": "chdemko/sorted-collections", + "version": "1.0.10", + "source": { + "type": "git", + "url": "https://github.com/chdemko/php-sorted-collections.git", + "reference": "d9cf7021e6fda1eb68b9f35caf99215327f6db76" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chdemko/php-sorted-collections/zipball/d9cf7021e6fda1eb68b9f35caf99215327f6db76", + "reference": "d9cf7021e6fda1eb68b9f35caf99215327f6db76", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.7", + "phpbench/phpbench": "^1.3", + "phpunit/phpunit": "^11.3", + "squizlabs/php_codesniffer": "^3.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "chdemko\\SortedCollection\\": "src/SortedCollection" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Christophe Demko", + "email": "chdemko@gmail.com", + "homepage": "https://chdemko.pagelab.univ-lr.fr/", + "role": "Developer" + } + ], + "description": "Sorted Collections for PHP >= 8.1", + "homepage": "https://php-sorted-collections.readthedocs.io/en/latest/?badge=latest", + "keywords": [ + "avl", + "collection", + "iterator", + "map", + "ordered", + "set", + "sorted", + "tree", + "treemap", + "treeset" + ], + "support": { + "issues": "https://github.com/chdemko/php-sorted-collections/issues", + "source": "https://github.com/chdemko/php-sorted-collections/tree/1.0.10" + }, + "time": "2024-08-04T14:31:40+00:00" }, { "name": "jfcherng/php-color-output", diff --git a/endpoints/account/account.php b/endpoints/account/account.php index c163ed6c..5c4ed8dd 100644 --- a/endpoints/account/account.php +++ b/endpoints/account/account.php @@ -54,7 +54,7 @@ class AccountBaseResponse extends TemplateResponse { array_unshift($this->title, Lang::account('settings')); - $user = DB::Aowow()->selectRow('SELECT `debug`, `email`, `description`, `avatar`, `wowicon`, `renameCooldown` FROM ?_account WHERE `id` = ?d', User::$id); + $user = DB::Aowow()->selectRow('SELECT `debug`, `email`, `description`, `avatar`, `wowicon`, `renameCooldown` FROM ::account WHERE `id` = %i', User::$id); Lang::sort('game', 'ra'); @@ -65,11 +65,11 @@ class AccountBaseResponse extends TemplateResponse /* Ban Popup */ /*************/ - $b = DB::Aowow()->select( + $b = DB::Aowow()->selectAssoc( 'SELECT ab.`end` AS "0", ab.`reason` AS "1", a.`username` AS "2" - FROM ?_account_banned ab - LEFT JOIN ?_account a ON a.`id` = ab.`staffId` - WHERE ab.`userId` = ?d AND ab.`typeMask` & ?d AND (ab.`end` = 0 OR ab.`end` > UNIX_TIMESTAMP())', + FROM ::account_banned ab + LEFT JOIN ::account a ON a.`id` = ab.`staffId` + WHERE ab.`userId` = %i AND ab.`typeMask` & %i AND (ab.`end` = 0 OR ab.`end` > UNIX_TIMESTAMP())', User::$id, ACC_BAN_TEMP | ACC_BAN_PERM ); @@ -99,7 +99,7 @@ class AccountBaseResponse extends TemplateResponse /* GENERAL */ // Modelviewer - if ($_ = DB::Aowow()->selectCell('SELECT `data` FROM ?_account_cookies WHERE `name` = ? AND `userId` = ?d', 'default_3dmodel', User::$id)) + if ($_ = DB::Aowow()->selectCell('SELECT `data` FROM ::account_cookies WHERE `name` = %s AND `userId` = %i', 'default_3dmodel', User::$id)) [$this->modelrace, $this->modelgender] = explode(',', $_); // Lists @@ -115,7 +115,7 @@ class AccountBaseResponse extends TemplateResponse $this->renameCD = DateTime::formatTimeElapsedFloat(Cfg::get('ACC_RENAME_DECAY') * 1000); if ($user['renameCooldown'] > time()) { - $locCode = implode('_', str_split(Lang::getLocale()->json(), 2)); // ._. + $locCode = substr_replace(Lang::getLocale()->json(), '_', 2, 0); // ._. $this->activeCD = (new \IntlDateFormatter($locCode, pattern: Lang::main('dateFmtIntl')))->format($user['renameCooldown']); } @@ -145,7 +145,7 @@ class AccountBaseResponse extends TemplateResponse // * 'when': uploaded timestamp expected as msec for some reason // * 'caption': only used for getVisibleText, duplicates name? // * 'type': always 1 ?, Dialog-popup doesn't work without it - if ($cuAvatars = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `id`, `name`, `name` AS "caption", `current`, `size`, `status`, `when` * 1000 AS "when", 1 AS "type" FROM ?_account_avatars WHERE `userId` = ?d', User::$id)) + if ($cuAvatars = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `id`, `name`, `name` AS "caption", `current`, `size`, `status`, `when` * 1000 AS "when", 1 AS "type" FROM ::account_avatars WHERE `userId` = %i', User::$id)) { foreach ($cuAvatars as $id => $a) if ($a['status'] != AvatarMgr::STATUS_REJECTED) diff --git a/endpoints/account/activate.php b/endpoints/account/activate.php index d437d75c..e56fad9e 100644 --- a/endpoints/account/activate.php +++ b/endpoints/account/activate.php @@ -52,13 +52,13 @@ class AccountActivateResponse extends TemplateResponse if (!$this->assertGET('key')) return Lang::main('intError'); - if (DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE `status` IN (?a) AND `token` = ?', [ACC_STATUS_NONE, ACC_STATUS_NEW], $this->_get['key'])) + if (DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE `status` IN %in AND `token` = %s', [ACC_STATUS_NONE, ACC_STATUS_NEW], $this->_get['key'])) { // don't remove the token yet. It's needed on signin page. - DB::Aowow()->query('UPDATE ?_account SET `status` = ?d, `statusTimer` = 0, `userGroups` = ?d WHERE `token` = ?', ACC_STATUS_NONE, U_GROUP_NONE, $this->_get['key']); + DB::Aowow()->qry('UPDATE ::account SET `status` = %i, `statusTimer` = 0, `userGroups` = %i WHERE `token` = %s', ACC_STATUS_NONE, U_GROUP_NONE, $this->_get['key']); // fully apply block for further registration attempts from this ip - DB::Aowow()->query('REPLACE INTO ?_account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (?, ?d, ?d + 1, UNIX_TIMESTAMP() + ?d)', + DB::Aowow()->qry('REPLACE INTO ::account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (%s, %i, %i + 1, UNIX_TIMESTAMP() + %i)', User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT, Cfg::get('ACC_FAILED_AUTH_COUNT'), Cfg::get('ACC_FAILED_AUTH_BLOCK')); $this->success = true; diff --git a/endpoints/account/confirm-delete.php b/endpoints/account/confirm-delete.php index 440dc415..c0cdcbdc 100644 --- a/endpoints/account/confirm-delete.php +++ b/endpoints/account/confirm-delete.php @@ -54,14 +54,14 @@ class AccountConfirmdeleteResponse extends TemplateResponse $msg = Lang::account('inputbox', 'error', 'purgeTokenUsed'); // display default confirm template - if ($this->assertGET('key') && DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE `status` = ?d AND `statusTimer` > UNIX_TIMESTAMP() AND `token` = ?', ACC_STATUS_PURGING, $this->_get['key'])) + if ($this->assertGET('key') && DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE `status` = %i AND `statusTimer` > UNIX_TIMESTAMP() AND `token` = %s', ACC_STATUS_PURGING, $this->_get['key'])) { $this->key = $this->_get['key']; return; } // perform action and display status - if ($this->assertPOST('key') && ($userId = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE `status` = ?d AND `statusTimer` > UNIX_TIMESTAMP() AND `token` = ?', ACC_STATUS_PURGING, $this->_post['key']))) + if ($this->assertPOST('key') && ($userId = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE `status` = %i AND `statusTimer` > UNIX_TIMESTAMP() AND `token` = %s', ACC_STATUS_PURGING, $this->_post['key']))) { if ($this->_post['cancel']) $msg = $this->cancel($userId); @@ -79,7 +79,7 @@ class AccountConfirmdeleteResponse extends TemplateResponse private function cancel(int $userId) : string { - if (DB::Aowow()->query('UPDATE ?_account SET `status` = ?d, `statusTimer` = 0, `token` = "" WHERE `id` = ?d', ACC_STATUS_NONE, $userId)) + if (DB::Aowow()->qry('UPDATE ::account SET `status` = %i, `statusTimer` = 0, `token` = "" WHERE `id` = %i', ACC_STATUS_NONE, $userId)) { $this->success = true; return Lang::account('inputbox', 'message', 'deleteCancel'); @@ -91,32 +91,32 @@ class AccountConfirmdeleteResponse extends TemplateResponse private function purge(int $userId) : string { // empty all user settings and cookies - DB::Aowow()->query('DELETE FROM ?_account_cookies WHERE `userId` = ?d', $userId); - DB::Aowow()->query('DELETE FROM ?_account_avatars WHERE `userId` = ?d', $userId); - DB::Aowow()->query('DELETE FROM ?_account_excludes WHERE `userId` = ?d', $userId); - DB::Aowow()->query('DELETE FROM ?_account_favorites WHERE `userId` = ?d', $userId); - DB::Aowow()->query('DELETE FROM ?_account_reputation WHERE `userId` = ?d', $userId); - DB::Aowow()->query('DELETE FROM ?_account_weightscales WHERE `userId` = ?d', $userId); // cascades to aowow_account_weightscale_data + DB::Aowow()->qry('DELETE FROM ::account_cookies WHERE `userId` = %i', $userId); + DB::Aowow()->qry('DELETE FROM ::account_avatars WHERE `userId` = %i', $userId); + DB::Aowow()->qry('DELETE FROM ::account_excludes WHERE `userId` = %i', $userId); + DB::Aowow()->qry('DELETE FROM ::account_favorites WHERE `userId` = %i', $userId); + DB::Aowow()->qry('DELETE FROM ::account_reputation WHERE `userId` = %i', $userId); + DB::Aowow()->qry('DELETE FROM ::account_weightscales WHERE `userId` = %i', $userId); // cascades to aowow_account_weightscale_data // delete profiles, unlink chars - DB::Aowow()->query('DELETE pp FROM ?_profiler_profiles pp JOIN ?_account_profiles ap ON ap.`profileId` = pp.`id` WHERE ap.`accountId` = ?d', $userId); - // DB::Aowow()->query('DELETE FROM ?_account_profiles WHERE `accountId` = ?d', $userId); // already deleted via FK? + DB::Aowow()->qry('DELETE pp FROM ::profiler_profiles pp JOIN ::account_profiles ap ON ap.`profileId` = pp.`id` WHERE ap.`accountId` = %i', $userId); + // DB::Aowow()->qry('DELETE FROM ::account_profiles WHERE `accountId` = %i', $userId); // already deleted via FK? // delete all sessions and bans - DB::Aowow()->query('DELETE FROM ?_account_banned WHERE `userId` = ?d', $userId); - DB::Aowow()->query('DELETE FROM ?_account_sessions WHERE `userId` = ?d', $userId); + DB::Aowow()->qry('DELETE FROM ::account_banned WHERE `userId` = %i', $userId); + DB::Aowow()->qry('DELETE FROM ::account_sessions WHERE `userId` = %i', $userId); // delete forum posts (msg: This post was from a user who has deleted their account. (no translations at src); comments/replies are unaffected) // ... // replace username with userId and empty fields - DB::Aowow()->query( - 'UPDATE ?_account SET + DB::Aowow()->qry( + 'UPDATE ::account SET `login` = "", `passHash` = "", `username` = `id`, `email` = NULL, `userGroups` = 0, `userPerms` = 0, `curIp` = "", `prevIp` = "", `curLogin` = 0, `prevLogin` = 0, `locale` = 0, `debug` = 0, `avatar` = 0, `wowicon` = "", `title` = "", `description` = "", `excludeGroups` = 0, - `status` = ?d, `statusTimer` = 0, `token` = "", `updateValue` = "", `renameCooldown` = 0 - WHERE `id` = ?d', + `status` = %i, `statusTimer` = 0, `token` = "", `updateValue` = "", `renameCooldown` = 0 + WHERE `id` = %i', ACC_STATUS_DELETED, $userId ); diff --git a/endpoints/account/confirm-email-address.php b/endpoints/account/confirm-email-address.php index eb11801c..05a4f217 100644 --- a/endpoints/account/confirm-email-address.php +++ b/endpoints/account/confirm-email-address.php @@ -46,12 +46,12 @@ class AccountConfirmemailaddressResponse extends TemplateResponse if (!$this->assertGET('key')) return Lang::main('intError'); - $acc = DB::Aowow()->selectRow('SELECT `updateValue`, `status`, `statusTimer` FROM ?_account WHERE `token` = ?', $this->_get['key']); + $acc = DB::Aowow()->selectRow('SELECT `updateValue`, `status`, `statusTimer` FROM ::account WHERE `token` = %s', $this->_get['key']); if (!$acc || $acc['status'] != ACC_STATUS_CHANGE_EMAIL || $acc['statusTimer'] < time()) return Lang::account('inputbox', 'error', 'mailTokenUsed'); // 0 changes == error - if (!DB::Aowow()->query('UPDATE ?_account SET `email` = `updateValue`, `status` = ?d, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `token` = ?', ACC_STATUS_NONE, $this->_get['key'])) + if (!DB::Aowow()->qry('UPDATE ::account SET `email` = `updateValue`, `status` = %i, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `token` = %s', ACC_STATUS_NONE, $this->_get['key'])) return Lang::main('intError'); $this->success = true; diff --git a/endpoints/account/confirm-password.php b/endpoints/account/confirm-password.php index 4eec91f0..bc972f70 100644 --- a/endpoints/account/confirm-password.php +++ b/endpoints/account/confirm-password.php @@ -44,12 +44,12 @@ class AccountConfirmpasswordResponse extends TemplateResponse if (!$this->assertGET('key')) return Lang::main('intError'); - $acc = DB::Aowow()->selectRow('SELECT `updateValue`, `status`, `statusTimer` FROM ?_account WHERE `token` = ?', $this->_get['key']); + $acc = DB::Aowow()->selectRow('SELECT `updateValue`, `status`, `statusTimer` FROM ::account WHERE `token` = %s', $this->_get['key']); if (!$acc || $acc['status'] != ACC_STATUS_CHANGE_PASS || $acc['statusTimer'] < time()) return Lang::account('inputbox', 'error', 'passTokenUsed'); // 0 changes == error - if (!DB::Aowow()->query('UPDATE ?_account SET `passHash` = `updateValue`, `status` = ?d, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `token` = ?', ACC_STATUS_NONE, $this->_get['key'])) + if (!DB::Aowow()->qry('UPDATE ::account SET `passHash` = `updateValue`, `status` = %i, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `token` = %s', ACC_STATUS_NONE, $this->_get['key'])) return Lang::main('intError'); $this->success = true; diff --git a/endpoints/account/delete-icon.php b/endpoints/account/delete-icon.php index e70ea64a..4e71147b 100644 --- a/endpoints/account/delete-icon.php +++ b/endpoints/account/delete-icon.php @@ -28,15 +28,15 @@ class AccountDeleteiconResponse extends TextResponse return; // non-int > error - $selected = DB::Aowow()->selectCell('SELECT `current` FROM ?_account_avatars WHERE `id` = ?d AND `userId` = ?d', $this->_post['id'], User::$id); + $selected = DB::Aowow()->selectCell('SELECT `current` FROM ::account_avatars WHERE `id` = %i AND `userId` = %i', $this->_post['id'], User::$id); if ($selected === null || $selected === false) return; - DB::Aowow()->query('DELETE FROM ?_account_avatars WHERE `id` = ?d AND `userId` = ?d', $this->_post['id'], User::$id); + DB::Aowow()->qry('DELETE FROM ::account_avatars WHERE `id` = %i AND `userId` = %i', $this->_post['id'], User::$id); // if deleted avatar is also currently selected, unset if ($selected) - DB::Aowow()->query('UPDATE ?_account SET `avatar` = 0 WHERE `id` = ?d', User::$id); + DB::Aowow()->qry('UPDATE ::account SET `avatar` = 0 WHERE `id` = %i', User::$id); $path = sprintf('static/uploads/avatars/%d.jpg', $this->_post['id']); if (!unlink($path)) diff --git a/endpoints/account/delete.php b/endpoints/account/delete.php index 6828481d..04a46e2b 100644 --- a/endpoints/account/delete.php +++ b/endpoints/account/delete.php @@ -47,11 +47,11 @@ class AccountDeleteResponse extends TemplateResponse if ($this->_post['proceed']) { $error = false; - if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE `status` NOT IN (?a) AND `statusTimer` > UNIX_TIMESTAMP() AND `id` = ?d', [ACC_STATUS_NEW, ACC_STATUS_NONE, ACC_STATUS_PURGING], User::$id)) + if (!DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE `status` NOT IN %in AND `statusTimer` > UNIX_TIMESTAMP() AND `id` = %i', [ACC_STATUS_NEW, ACC_STATUS_NONE, ACC_STATUS_PURGING], User::$id)) { $token = Util::createHash(40); - DB::Aowow()->query('UPDATE ?_account SET `status` = ?d, `statusTimer` = UNIX_TIMESTAMP() + ?d, `token` = ? WHERE `id` = ?d', + DB::Aowow()->qry('UPDATE ::account SET `status` = %i, `statusTimer` = UNIX_TIMESTAMP() + %i, `token` = %s WHERE `id` = %i', ACC_STATUS_PURGING, Cfg::get('ACC_RECOVERY_DECAY'), $token, User::$id); Util::sendMail(User::$email, 'delete-account', [$token, User::$email, User::$username]); diff --git a/endpoints/account/exclude.php b/endpoints/account/exclude.php index c94a8f82..17a3a032 100644 --- a/endpoints/account/exclude.php +++ b/endpoints/account/exclude.php @@ -49,12 +49,17 @@ class AccountExcludeResponse extends TextResponse // we don't get signaled whether an id should be added to or removed from either includes or excludes // so we throw everything into one table and toggle the mode if its already in here - $includes = DB::Aowow()->selectCol('SELECT `typeId` FROM ?_profiler_excludes WHERE `type` = ?d AND `typeId` IN (?a)', $this->_post['type'], $validIds); - + $includes = DB::Aowow()->selectCol('SELECT `typeId` FROM ::profiler_excludes WHERE `type` = %i AND `typeId` IN %in', $this->_post['type'], $validIds); + $insert = []; foreach ($validIds as $typeId) - DB::Aowow()->query('INSERT INTO ?_account_excludes (`userId`, `type`, `typeId`, `mode`) VALUES (?a) ON DUPLICATE KEY UPDATE `mode` = (`mode` ^ 0x3)', - [User::$id, $this->_post['type'], $typeId, in_array($typeId, $includes) ? 2 : 1] - ); + { + $insert['userId'][] = User::$id; + $insert['type'][] = $this->_post['type']; + $insert['typeId'][] = $typeId; + $insert['mode'][] = in_array($typeId, $includes) ? Profiler::COMPLETION_INCLUDE : Profiler::COMPLETION_EXCLUDE; + }; + + DB::Aowow()->qry('INSERT INTO ::account_excludes %m ON DUPLICATE KEY UPDATE `mode` = (`mode` ^ 0x3)', $insert); } else trigger_error('AccountExcludeResponse::excludeById - validation failed [type: '.$this->_post['type'].', typeId: '.implode(',', $this->_post['id']).']', E_USER_NOTICE); @@ -62,14 +67,14 @@ class AccountExcludeResponse extends TextResponse private function resetExcludes() : void { - DB::Aowow()->query('DELETE FROM ?_account_excludes WHERE `userId` = ?d', User::$id); - DB::Aowow()->query('UPDATE ?_account SET `excludeGroups` = ?d WHERE `id` = ?d', PR_EXCLUDE_GROUP_UNAVAILABLE, User::$id); + DB::Aowow()->qry('DELETE FROM ::account_excludes WHERE `userId` = %i', User::$id); + DB::Aowow()->qry('UPDATE ::account SET `excludeGroups` = %i WHERE `id` = %i', PR_EXCLUDE_GROUP_UNAVAILABLE, User::$id); } private function updateGroups() : void { if ($this->assertPOST('groups')) // clamp to real groups - DB::Aowow()->query('UPDATE ?_account SET `excludeGroups` = ?d WHERE `id` = ?d', $this->_post['groups'] & PR_EXCLUDE_GROUP_ANY, User::$id); + DB::Aowow()->qry('UPDATE ::account SET `excludeGroups` = %i WHERE `id` = %i', $this->_post['groups'] & PR_EXCLUDE_GROUP_ANY, User::$id); } } diff --git a/endpoints/account/favorites.php b/endpoints/account/favorites.php index 46641e10..e459d253 100644 --- a/endpoints/account/favorites.php +++ b/endpoints/account/favorites.php @@ -37,13 +37,13 @@ class AccountFavoritesResponse extends TextResponse private function removeFavorite() : void { if ($this->assertPOST('id', 'remove')) - DB::Aowow()->query('DELETE FROM ?_account_favorites WHERE `userId` = ?d AND `type` = ?d AND `typeId` = ?d', User::$id, $this->_post['remove'], $this->_post['id']); + DB::Aowow()->qry('DELETE FROM ::account_favorites WHERE `userId` = %i AND `type` = %i AND `typeId` = %i', User::$id, $this->_post['remove'], $this->_post['id']); } private function addFavorite() : void { if ($this->assertPOST('id', 'add') && Type::validateIds($this->_post['add'], $this->_post['id'])) - DB::Aowow()->query('INSERT INTO ?_account_favorites (`userId`, `type`, `typeId`) VALUES (?d, ?d, ?d)', User::$id, $this->_post['add'], $this->_post['id']); + DB::Aowow()->qry('INSERT INTO ::account_favorites (`userId`, `type`, `typeId`) VALUES (%i, %i, %i)', User::$id, $this->_post['add'], $this->_post['id']); else trigger_error('AccountFavoritesResponse::addFavorite() - failed to add [userId: '.User::$id.', type: '.$this->_post['add'].', typeId: '.$this->_post['id'], E_USER_NOTICE); } diff --git a/endpoints/account/forgot-password.php b/endpoints/account/forgot-password.php index a1e644c6..c0ab9581 100644 --- a/endpoints/account/forgot-password.php +++ b/endpoints/account/forgot-password.php @@ -72,14 +72,14 @@ class AccountforgotpasswordResponse extends TemplateResponse if (!$this->_post['email']) return Lang::account('emailInvalid'); - $timeout = DB::Aowow()->selectCell('SELECT `unbanDate` FROM ?_account_bannedips WHERE `ip` = ? AND `type` = ?d AND `count` > ?d AND `unbanDate` > UNIX_TIMESTAMP()', User::$ip, IP_BAN_TYPE_PASSWORD_RECOVERY, Cfg::get('ACC_FAILED_AUTH_COUNT')); + $timeout = DB::Aowow()->selectCell('SELECT `unbanDate` FROM ::account_bannedips WHERE `ip` = %s AND `type` = %i AND `count` > %i AND `unbanDate` > UNIX_TIMESTAMP()', User::$ip, IP_BAN_TYPE_PASSWORD_RECOVERY, Cfg::get('ACC_FAILED_AUTH_COUNT')); // on cooldown pretend we dont know the email address if ($timeout && $timeout > time()) return Cfg::get('DEBUG') ? 'resend on cooldown: '.DateTime::formatTimeElapsed($timeout * 1000).' remaining' : Lang::account('inputbox', 'error', 'emailNotFound'); // pretend recovery started - if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE `email` = ?', $this->_post['email'])) + if (!DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE `email` = %s', $this->_post['email'])) { // do not confirm or deny existence of email $this->success = !Cfg::get('DEBUG'); @@ -90,7 +90,7 @@ class AccountforgotpasswordResponse extends TemplateResponse if ($err = $this->startRecovery(ACC_STATUS_RECOVER_PASS, 'reset-password', $this->_post['email'])) return $err; - DB::Aowow()->query('INSERT INTO ?_account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (?, ?d, ?d, UNIX_TIMESTAMP() + ?d) ON DUPLICATE KEY UPDATE `count` = `count` + ?d, `unbanDate` = UNIX_TIMESTAMP() + ?d', + DB::Aowow()->qry('INSERT INTO ::account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (%s, %i, %i, UNIX_TIMESTAMP() + %i) ON DUPLICATE KEY UPDATE `count` = `count` + %i, `unbanDate` = UNIX_TIMESTAMP() + %i', User::$ip, IP_BAN_TYPE_PASSWORD_RECOVERY, Cfg::get('ACC_FAILED_AUTH_COUNT') + 1, Cfg::get('ACC_FAILED_AUTH_COUNT'), Cfg::get('ACC_FAILED_AUTH_BLOCK'), Cfg::get('ACC_FAILED_AUTH_BLOCK')); $this->success = true; diff --git a/endpoints/account/forgot-username.php b/endpoints/account/forgot-username.php index 6b946a0a..c1cff916 100644 --- a/endpoints/account/forgot-username.php +++ b/endpoints/account/forgot-username.php @@ -71,14 +71,14 @@ class AccountforgotusernameResponse extends TemplateResponse if (!$this->_post['email']) return Lang::account('emailInvalid'); - $timeout = DB::Aowow()->selectCell('SELECT `unbanDate` FROM ?_account_bannedips WHERE `ip` = ? AND `type` = ?d AND `count` > ?d AND `unbanDate` > UNIX_TIMESTAMP()', User::$ip, IP_BAN_TYPE_USERNAME_RECOVERY, Cfg::get('ACC_FAILED_AUTH_COUNT')); + $timeout = DB::Aowow()->selectCell('SELECT `unbanDate` FROM ::account_bannedips WHERE `ip` = %s AND `type` = %i AND `count` > %i AND `unbanDate` > UNIX_TIMESTAMP()', User::$ip, IP_BAN_TYPE_USERNAME_RECOVERY, Cfg::get('ACC_FAILED_AUTH_COUNT')); // on cooldown pretend we dont know the email address if ($timeout && $timeout > time()) return Cfg::get('DEBUG') ? 'resend on cooldown: '.DateTime::formatTimeElapsed($timeout * 1000).' remaining' : Lang::account('inputbox', 'error', 'emailNotFound'); // pretend recovery started - if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE `email` = ?', $this->_post['email'])) + if (!DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE `email` = %s', $this->_post['email'])) { // do not confirm or deny existence of email $this->success = !Cfg::get('DEBUG'); @@ -89,7 +89,7 @@ class AccountforgotusernameResponse extends TemplateResponse if ($err = $this->startRecovery(ACC_STATUS_RECOVER_USER, 'recover-user', $this->_post['email'])) return $err; - DB::Aowow()->query('INSERT INTO ?_account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (?, ?d, ?d, UNIX_TIMESTAMP() + ?d) ON DUPLICATE KEY UPDATE `count` = `count` + ?d, `unbanDate` = UNIX_TIMESTAMP() + ?d', + DB::Aowow()->qry('INSERT INTO ::account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (%s, %i, %i, UNIX_TIMESTAMP() + %i) ON DUPLICATE KEY UPDATE `count` = `count` + %i, `unbanDate` = UNIX_TIMESTAMP() + %i', User::$ip, IP_BAN_TYPE_USERNAME_RECOVERY, Cfg::get('ACC_FAILED_AUTH_COUNT') + 1, Cfg::get('ACC_FAILED_AUTH_COUNT'), Cfg::get('ACC_FAILED_AUTH_BLOCK'), Cfg::get('ACC_FAILED_AUTH_BLOCK')); $this->success = true; diff --git a/endpoints/account/forum-avatar.php b/endpoints/account/forum-avatar.php index a123d572..e7bd9840 100644 --- a/endpoints/account/forum-avatar.php +++ b/endpoints/account/forum-avatar.php @@ -48,7 +48,7 @@ class AccountForumavatarResponse extends TextResponse private function unset() : string { - $x = DB::Aowow()->query('UPDATE ?_account SET `avatar` = 0 WHERE `id` = ?d', User::$id); + $x = DB::Aowow()->qry('UPDATE ::account SET `avatar` = 0 WHERE `id` = %i', User::$id); if ($x === null || $x === false) return Lang::main('genericError'); @@ -64,17 +64,17 @@ class AccountForumavatarResponse extends TextResponse $icon = strtolower(trim($this->_post['wowicon'])); - if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_icons WHERE `name` = ?', $icon)) + if (!DB::Aowow()->selectCell('SELECT 1 FROM ::icons WHERE `name` = %s', $icon)) return Lang::account('updateMessage', 'avNotFound'); - $x = DB::Aowow()->query('UPDATE ?_account SET `avatar` = 1, `wowicon` = ? WHERE `id` = ?d', strtolower($icon), User::$id); - if ($x === null || $x === false) + $x = DB::Aowow()->qry('UPDATE ::account SET `avatar` = 1, `wowicon` = %s WHERE `id` = %i', $icon, User::$id); + if (is_null($x)) return Lang::main('genericError'); $this->success = true; $msg = Lang::account('updateMessage', $x === 0 ? 'avNoChange' : 'avSuccess'); - if (($qty = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_account WHERE `wowicon` = ?', $icon)) > 1) + if (($qty = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ::account WHERE `wowicon` = %s', $icon)) > 1) $msg .= ' '.Lang::account('updateMessage', 'avNthUser', [$qty]); else $msg .= ' '.Lang::account('updateMessage', 'av1stUser'); @@ -92,11 +92,11 @@ class AccountForumavatarResponse extends TextResponse $customIcon = $this->_post['customicon'] ?? $this->_get['customicon']; - $x = DB::Aowow()->query('UPDATE ?_account_avatars SET `current` = IF(`id` = ?d, 1, 0) WHERE `userId` = ?d AND `status` <> ?d', $customIcon, User::$id, AvatarMgr::STATUS_REJECTED); + $x = DB::Aowow()->qry('UPDATE ::account_avatars SET `current` = IF(`id` = %i, 1, 0) WHERE `userId` = %i AND `status` <> %i', $customIcon, User::$id, AvatarMgr::STATUS_REJECTED); if (!is_int($x)) return Lang::main('genericError'); - if (!is_int(DB::Aowow()->query('UPDATE ?_account SET `avatar` = 2 WHERE `id` = ?d', User::$id))) + if (!is_int(DB::Aowow()->qry('UPDATE ::account SET `avatar` = 2 WHERE `id` = %i', User::$id))) return Lang::main('intError'); $this->success = true; diff --git a/endpoints/account/premium-border.php b/endpoints/account/premium-border.php index e1ee43d8..7374a210 100644 --- a/endpoints/account/premium-border.php +++ b/endpoints/account/premium-border.php @@ -28,8 +28,8 @@ class AccountPremiumborderResponse extends TextResponse if (!$this->assertPOST('avatarborder')) return; - $x = DB::Aowow()->query('UPDATE ?_account SET `avatarborder` = ?d WHERE `id` = ?d', $this->_post['avatarborder'], User::$id); - if (!is_int($x)) + $x = DB::Aowow()->qry('UPDATE ::account SET `avatarborder` = %i WHERE `id` = %i', $this->_post['avatarborder'], User::$id); + if (is_null($x)) $_SESSION['msg'] = ['premiumborder', false, Lang::main('genericError')]; else if (!$x) $_SESSION['msg'] = ['premiumborder', true, Lang::account('updateMessage', 'avNoChange')]; diff --git a/endpoints/account/rename-icon.php b/endpoints/account/rename-icon.php index 46735d01..c88ff2bb 100644 --- a/endpoints/account/rename-icon.php +++ b/endpoints/account/rename-icon.php @@ -29,7 +29,7 @@ class AccountRenameiconResponse extends TextResponse return; // regexp same as in account.js - DB::Aowow()->query('UPDATE ?_account_avatars SET `name` = ? WHERE `id` = ?d AND `userId` = ?d', trim($this->_post['name']), $this->_post['id'], User::$id); + DB::Aowow()->qry('UPDATE ::account_avatars SET `name` = %s WHERE `id` = %i AND `userId` = %i', trim($this->_post['name']), $this->_post['id'], User::$id); } } diff --git a/endpoints/account/resend.php b/endpoints/account/resend.php index fc6baee3..7c1fecbf 100644 --- a/endpoints/account/resend.php +++ b/endpoints/account/resend.php @@ -69,19 +69,19 @@ class AccountResendResponse extends TemplateResponse if (!$this->_post['email']) return Lang::account('emailInvalid'); - $timeout = DB::Aowow()->selectCell('SELECT `unbanDate` FROM ?_account_bannedips WHERE `ip` = ? AND `type` = ?d AND `count` > ?d AND `unbanDate` > UNIX_TIMESTAMP()', User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT, Cfg::get('ACC_FAILED_AUTH_COUNT')); + $timeout = DB::Aowow()->selectCell('SELECT `unbanDate` FROM ::account_bannedips WHERE `ip` = %s AND `type` = %i AND `count` > %i AND `unbanDate` > UNIX_TIMESTAMP()', User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT, Cfg::get('ACC_FAILED_AUTH_COUNT')); // on cooldown pretend we dont know the email address if ($timeout && $timeout > time()) return Cfg::get('DEBUG') ? 'resend on cooldown: '.DateTime::formatTimeElapsed($timeout * 1000).' remaining' : Lang::account('inputbox', 'error', 'emailNotFound'); // check email and account status - if ($token = DB::Aowow()->selectCell('SELECT `token` FROM ?_account WHERE `email` = ? AND `status` = ?d', $this->_post['email'], ACC_STATUS_NEW)) + if ($token = DB::Aowow()->selectCell('SELECT `token` FROM ::account WHERE `email` = %s AND `status` = %i', $this->_post['email'], ACC_STATUS_NEW)) { if (!Util::sendMail($this->_post['email'], 'activate-account', [$token])) return Lang::main('intError'); - DB::Aowow()->query('INSERT INTO ?_account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (?, ?d, ?d, UNIX_TIMESTAMP() + ?d) ON DUPLICATE KEY UPDATE `count` = `count` + ?d, `unbanDate` = UNIX_TIMESTAMP() + ?d', + DB::Aowow()->qry('INSERT INTO ::account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (%s, %i, %i, UNIX_TIMESTAMP() + %i) ON DUPLICATE KEY UPDATE `count` = `count` + %i, `unbanDate` = UNIX_TIMESTAMP() + %i', User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT, Cfg::get('ACC_FAILED_AUTH_COUNT') + 1, Cfg::get('ACC_FAILED_AUTH_COUNT'), Cfg::get('ACC_FAILED_AUTH_BLOCK'), Cfg::get('ACC_FAILED_AUTH_BLOCK')); $this->success = true; diff --git a/endpoints/account/reset-password.php b/endpoints/account/reset-password.php index c9abf6a8..4d71153f 100644 --- a/endpoints/account/reset-password.php +++ b/endpoints/account/reset-password.php @@ -59,7 +59,7 @@ class AccountresetpasswordResponse extends TemplateResponse $errMsg = ''; if (!$this->assertGET('key') && !$this->assertPOST('key')) $errMsg = Lang::account('inputbox', 'error', 'passTokenLost'); - else if ($this->_get['key'] && !DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE `token` = ? AND `status` = ?d AND `statusTimer` > UNIX_TIMESTAMP()', $this->_get['key'], ACC_STATUS_RECOVER_PASS)) + else if ($this->_get['key'] && !DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE `token` = %s AND `status` = %i AND `statusTimer` > UNIX_TIMESTAMP()', $this->_get['key'], ACC_STATUS_RECOVER_PASS)) $errMsg = Lang::account('inputbox', 'error', 'passTokenUsed'); if ($errMsg) @@ -99,7 +99,7 @@ class AccountresetpasswordResponse extends TemplateResponse if ($this->_post['password'] != $this->_post['c_password']) return Lang::account('passCheckFail'); - $userData = DB::Aowow()->selectRow('SELECT `id`, `passHash` FROM ?_account WHERE `token` = ? AND `email` = ? AND `status` = ?d AND `statusTimer` > UNIX_TIMESTAMP()', + $userData = DB::Aowow()->selectRow('SELECT `id`, `passHash` FROM ::account WHERE `token` = %s AND `email` = %s AND `status` = %i AND `statusTimer` > UNIX_TIMESTAMP()', $this->_post['key'], $this->_post['email'], ACC_STATUS_RECOVER_PASS @@ -110,7 +110,7 @@ class AccountresetpasswordResponse extends TemplateResponse if (!User::verifyCrypt($this->_post['c_password'], $userData['passHash'])) return Lang::account('newPassDiff'); - if (!DB::Aowow()->query('UPDATE ?_account SET `passHash` = ?, `status` = ?d WHERE `id` = ?d', User::hashCrypt($this->_post['c_password']), ACC_STATUS_NONE, $userData['id'])) + if (!DB::Aowow()->qry('UPDATE ::account SET `passHash` = %s, `status` = %i WHERE `id` = %i', User::hashCrypt($this->_post['c_password']), ACC_STATUS_NONE, $userData['id'])) return Lang::main('intError'); $this->success = true; diff --git a/endpoints/account/revert-email-address.php b/endpoints/account/revert-email-address.php index 37475082..106fb6f0 100644 --- a/endpoints/account/revert-email-address.php +++ b/endpoints/account/revert-email-address.php @@ -46,12 +46,12 @@ class AccountRevertemailaddressResponse extends TemplateResponse if (!$this->assertGET('key')) return Lang::main('intError'); - $acc = DB::Aowow()->selectRow('SELECT `updateValue`, `status`, `statusTimer` FROM ?_account WHERE `token` = ?', $this->_get['key']); + $acc = DB::Aowow()->selectRow('SELECT `updateValue`, `status`, `statusTimer` FROM ::account WHERE `token` = %s', $this->_get['key']); if (!$acc || $acc['status'] != ACC_STATUS_CHANGE_EMAIL || $acc['statusTimer'] < time()) return Lang::account('inputbox', 'error', 'mailTokenUsed'); // 0 changes == error - if (!DB::Aowow()->query('UPDATE ?_account SET `status` = ?d, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `token` = ?', ACC_STATUS_NONE, $this->_get['key'])) + if (!DB::Aowow()->qry('UPDATE ::account SET `status` = %i, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `token` = %s', ACC_STATUS_NONE, $this->_get['key'])) return Lang::main('intError'); $this->success = true; diff --git a/endpoints/account/signin.php b/endpoints/account/signin.php index 9beea099..ed8fbf07 100644 --- a/endpoints/account/signin.php +++ b/endpoints/account/signin.php @@ -53,7 +53,7 @@ class AccountSigninResponse extends TemplateResponse // coming from user recovery or creation, prefill username if ($this->_get['key']) { - if ($userData = DB::Aowow()->selectRow('SELECT a.`login` AS "0", IF(s.`expires`, 0, 1) AS "1" FROM ?_account a LEFT JOIN ?_account_sessions s ON a.`id` = s.`userId` AND a.`token` = s.`sessionId` WHERE a.`status` IN (?a) AND a.`token` = ?', + if ($userData = DB::Aowow()->selectRow('SELECT a.`login` AS "0", IF(s.`expires`, 0, 1) AS "1" FROM ::account a LEFT JOIN ::account_sessions s ON a.`id` = s.`userId` AND a.`token` = s.`sessionId` WHERE a.`status` IN %in AND a.`token` = %s', [ACC_STATUS_RECOVER_USER, ACC_STATUS_NONE], $this->_get['key'])) [$username, $rememberMe] = $userData; } @@ -116,7 +116,7 @@ class AccountSigninResponse extends TemplateResponse } // reset account status, update expiration - $ok = DB::Aowow()->query('UPDATE ?_account SET `prevIP` = IF(`curIp` = ?, `prevIP`, `curIP`), `curIP` = IF(`curIp` = ?, `curIP`, ?), `status` = IF(`status` = ?d, `status`, 0), `statusTimer` = IF(`status` = ?d, `statusTimer`, 0), `token` = IF(`status` = ?d, `token`, "") WHERE `id` = ?d', + $ok = DB::Aowow()->qry('UPDATE ::account SET `prevIP` = IF(`curIp` = %s, `prevIP`, `curIP`), `curIP` = IF(`curIp` = %s, `curIP`, %s), `status` = IF(`status` = %i, `status`, 0), `statusTimer` = IF(`status` = %i, `statusTimer`, 0), `token` = IF(`status` = %i, `token`, "") WHERE `id` = %i', User::$ip, User::$ip, User::$ip, ACC_STATUS_NEW, ACC_STATUS_NEW, ACC_STATUS_NEW, User::$id // available after successful User:authenticate @@ -130,12 +130,12 @@ class AccountSigninResponse extends TemplateResponse // DELETE temp session if ($this->_get['key']) - DB::Aowow()->query('DELETE FROM ?_account_sessions WHERE `sessionId` = ?', $this->_get['key']); + DB::Aowow()->qry('DELETE FROM ::account_sessions WHERE `sessionId` = %s', $this->_get['key']); session_regenerate_id(true); // user status changed => regenerate id // create new session entry - DB::Aowow()->query('INSERT INTO ?_account_sessions (`userId`, `sessionId`, `created`, `expires`, `touched`, `deviceInfo`, `ip`, `status`) VALUES (?d, ?, ?d, ?d, ?d, ?, ?, ?d)', + DB::Aowow()->qry('INSERT INTO ::account_sessions (`userId`, `sessionId`, `created`, `expires`, `touched`, `deviceInfo`, `ip`, `status`) VALUES (%i, %s, %i, %i, %i, %s, %s, %i)', User::$id, session_id(), time(), $this->_post['remember_me'] ? 0 : time() + Cfg::get('SESSION_TIMEOUT_DELAY'), time(), User::$agent, User::$ip, SESSION_ACTIVE); if (User::init()) // reinitialize the user diff --git a/endpoints/account/signout.php b/endpoints/account/signout.php index 7f96e56e..73374d1b 100644 --- a/endpoints/account/signout.php +++ b/endpoints/account/signout.php @@ -27,9 +27,9 @@ class AccountSignoutResponse extends TextResponse protected function generate() : void { if ($this->_get['global']) - DB::Aowow()->query('UPDATE ?_account_sessions SET `touched` = ?d, `status` = ?d WHERE `userId` = ?d', time(), SESSION_FORCED_LOGOUT, User::$id); + DB::Aowow()->qry('UPDATE ::account_sessions SET `touched` = %i, `status` = %i WHERE `userId` = %i', time(), SESSION_FORCED_LOGOUT, User::$id); else - DB::Aowow()->query('UPDATE ?_account_sessions SET `touched` = ?d, `status` = ?d WHERE `sessionId` = ?', time(), SESSION_LOGOUT, session_id()); + DB::Aowow()->qry('UPDATE ::account_sessions SET `touched` = %i, `status` = %i WHERE `sessionId` = %s', time(), SESSION_LOGOUT, session_id()); User::destroy(); diff --git a/endpoints/account/signup.php b/endpoints/account/signup.php index af3181dd..2fa29278 100644 --- a/endpoints/account/signup.php +++ b/endpoints/account/signup.php @@ -109,24 +109,24 @@ class AccountSignupResponse extends TemplateResponse return Lang::main('intError'); // limit account creation - if (DB::Aowow()->selectRow('SELECT 1 FROM ?_account_bannedips WHERE `type` = ?d AND `ip` = ? AND `count` >= ?d AND `unbanDate` >= UNIX_TIMESTAMP()', IP_BAN_TYPE_REGISTRATION_ATTEMPT, User::$ip, Cfg::get('ACC_FAILED_AUTH_COUNT'))) + if (DB::Aowow()->selectRow('SELECT 1 FROM ::account_bannedips WHERE `type` = %i AND `ip` = %s AND `count` >= %i AND `unbanDate` >= UNIX_TIMESTAMP()', IP_BAN_TYPE_REGISTRATION_ATTEMPT, User::$ip, Cfg::get('ACC_FAILED_AUTH_COUNT'))) { - DB::Aowow()->query('UPDATE ?_account_bannedips SET `count` = `count` + 1, `unbanDate` = UNIX_TIMESTAMP() + ?d WHERE `ip` = ? AND `type` = ?d', Cfg::get('ACC_FAILED_AUTH_BLOCK'), User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT); + DB::Aowow()->qry('UPDATE ::account_bannedips SET `count` = `count` + 1, `unbanDate` = UNIX_TIMESTAMP() + %i WHERE `ip` = %s AND `type` = %i', Cfg::get('ACC_FAILED_AUTH_BLOCK'), User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT); return Lang::account('inputbox', 'error', 'signupExceeded', [DateTime::formatTimeElapsedFloat(Cfg::get('ACC_FAILED_AUTH_BLOCK') * 1000)]); } // username / email taken - if ($inUseData = DB::Aowow()->SelectRow('SELECT `id`, `username`, `status` = ?d AND `statusTimer` < UNIX_TIMESTAMP() AS "expired" FROM ?_account WHERE (LOWER(`username`) = LOWER(?) OR LOWER(`email`) = LOWER(?))', ACC_STATUS_NEW, $this->_post['username'], $this->_post['email'])) + if ($inUseData = DB::Aowow()->SelectRow('SELECT `id`, `username`, `status` = %i AND `statusTimer` < UNIX_TIMESTAMP() AS "expired" FROM ::account WHERE (LOWER(`username`) = LOWER(%s) OR LOWER(`email`) = LOWER(%s))', ACC_STATUS_NEW, $this->_post['username'], $this->_post['email'])) { if ($inUseData['expired']) - DB::Aowow()->query('DELETE FROM ?_account WHERE `id` = ?d', $inUseData['id']); + DB::Aowow()->qry('DELETE FROM ::account WHERE `id` = %i', $inUseData['id']); else return Util::lower($inUseData['username']) == Util::lower($this->_post['username']) ? Lang::account('nameInUse') : Lang::account('mailInUse'); } // create.. $token = Util::createHash(); - $userId = DB::Aowow()->query('INSERT INTO ?_account (`login`, `passHash`, `username`, `email`, `joindate`, `curIP`, `locale`, `userGroups`, `status`, `statusTimer`, `token`) VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(), ?, ?d, ?d, ?d, UNIX_TIMESTAMP() + ?d, ?)', + $userId = DB::Aowow()->qry('INSERT INTO ::account (`login`, `passHash`, `username`, `email`, `joindate`, `curIP`, `locale`, `userGroups`, `status`, `statusTimer`, `token`) VALUES (%s, %s, %s, %s, UNIX_TIMESTAMP(), %s, %i, %i, %i, UNIX_TIMESTAMP() + %i, %s)', $this->_post['username'], User::hashCrypt($this->_post['password']), $this->_post['username'], @@ -143,14 +143,14 @@ class AccountSignupResponse extends TemplateResponse return Lang::main('intError'); // create session tied to the token to store remember_me status - DB::Aowow()->query('INSERT INTO ?_account_sessions (`userId`, `sessionId`, `created`, `expires`, `touched`, `deviceInfo`, `ip`, `status`) VALUES (?d, ?, ?d, ?d, ?d, ?, ?, ?d)', + DB::Aowow()->qry('INSERT INTO ::account_sessions (`userId`, `sessionId`, `created`, `expires`, `touched`, `deviceInfo`, `ip`, `status`) VALUES (%i, %s, %i, %i, %i, %s, %s, %i)', $userId, $token, time(), $this->_post['remember_me'] ? 0 : time() + Cfg::get('SESSION_TIMEOUT_DELAY'), time(), User::$agent, User::$ip, SESSION_ACTIVE); if (!Util::sendMail($this->_post['email'], 'activate-account', [$token], Cfg::get('ACC_CREATE_SAVE_DECAY'))) return Lang::main('intError2', ['send mail']); // success: update ip-bans - DB::Aowow()->query('INSERT INTO ?_account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (?, ?d, 1, UNIX_TIMESTAMP() + ?d) ON DUPLICATE KEY UPDATE `count` = `count` + 1, `unbanDate` = UNIX_TIMESTAMP() + ?d', + DB::Aowow()->qry('INSERT INTO ::account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (%s, %i, 1, UNIX_TIMESTAMP() + %i) ON DUPLICATE KEY UPDATE `count` = `count` + 1, `unbanDate` = UNIX_TIMESTAMP() + %i', User::$ip, IP_BAN_TYPE_REGISTRATION_ATTEMPT, Cfg::get('ACC_FAILED_AUTH_BLOCK'), Cfg::get('ACC_FAILED_AUTH_BLOCK')); Util::gainSiteReputation($userId, SITEREP_ACTION_REGISTER); diff --git a/endpoints/account/update-community-settings.php b/endpoints/account/update-community-settings.php index a09921f8..2bc1ed2d 100644 --- a/endpoints/account/update-community-settings.php +++ b/endpoints/account/update-community-settings.php @@ -37,7 +37,7 @@ class AccountUpdatecommunitysettingsResponse extends TextResponse return Lang::main('genericError'); // description - 0 modified rows is still success - if (!is_int(DB::Aowow()->query('UPDATE ?_account SET `description` = ? WHERE `id` = ?d', $this->_post['desc'], User::$id))) + if (!is_int(DB::Aowow()->qry('UPDATE ::account SET `description` = %s WHERE `id` = %i', $this->_post['desc'], User::$id))) return Lang::main('genericError'); $this->success = true; diff --git a/endpoints/account/update-email.php b/endpoints/account/update-email.php index caf5c63a..0cf750be 100644 --- a/endpoints/account/update-email.php +++ b/endpoints/account/update-email.php @@ -48,21 +48,21 @@ class AccountUpdateemailResponse extends TextResponse if (!$this->_post['newemail']) return Lang::account('emailInvalid'); - if (DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE `email` = ? AND `id` <> ?d', $this->_post['newemail'], User::$id)) + if (DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE `email` = %s AND `id` <> %i', $this->_post['newemail'], User::$id)) return Lang::account('mailInUse'); - $status = DB::Aowow()->selectCell('SELECT `status` FROM ?_account WHERE `statusTimer` > UNIX_TIMESTAMP() AND `id` = ?d', User::$id); + $status = DB::Aowow()->selectCell('SELECT `status` FROM ::account WHERE `statusTimer` > UNIX_TIMESTAMP() AND `id` = %i', User::$id); if ($status != ACC_STATUS_NONE && $status != ACC_STATUS_CHANGE_EMAIL) return Lang::account('inputbox', 'error', 'isRecovering', [DateTime::formatTimeElapsedFloat(Cfg::get('ACC_RECOVERY_DECAY') * 1000)]); - $oldEmail = DB::Aowow()->selectCell('SELECT `email` FROM ?_account WHERE `id` = ?d', User::$id); + $oldEmail = DB::Aowow()->selectCell('SELECT `email` FROM ::account WHERE `id` = %i', User::$id); if ($this->_post['newemail'] == $oldEmail) return Lang::account('newMailDiff'); $token = Util::createHash(); // store new mail in updateValue field, exchange when confirmation mail gets confirmed - if (!DB::Aowow()->query('UPDATE ?_account SET `updateValue` = ?, `status` = ?d, `statusTimer` = UNIX_TIMESTAMP() + ?d, `token` = ? WHERE `id` = ?d', + if (!DB::Aowow()->qry('UPDATE ::account SET `updateValue` = %s, `status` = %i, `statusTimer` = UNIX_TIMESTAMP() + %i, `token` = %s WHERE `id` = %i', $this->_post['newemail'], ACC_STATUS_CHANGE_EMAIL, Cfg::get('ACC_RECOVERY_DECAY'), $token, User::$id)) return Lang::main('intError'); diff --git a/endpoints/account/update-general-settings.php b/endpoints/account/update-general-settings.php index 6e56ce3a..73a8cda0 100644 --- a/endpoints/account/update-general-settings.php +++ b/endpoints/account/update-general-settings.php @@ -41,15 +41,15 @@ class AccountUpdategeneralsettingsResponse extends TextResponse if ($this->_post['modelrace'] && !ChrRace::tryFrom($this->_post['modelrace'])) return Lang::main('genericError'); - // js handles this as cookie, so saved as cookie; Q - also save in ?_account table? - if (!DB::Aowow()->query('REPLACE INTO ?_account_cookies (`userId`, `name`, `data`) VALUES (?d, ?, ?)', User::$id, 'default_3dmodel', $this->_post['modelrace']. ',' . $this->_post['modelgender'])) + // js handles this as cookie, so saved as cookie; Q - also save in ::account table? + if (!DB::Aowow()->qry('REPLACE INTO ::account_cookies (`userId`, `name`, `data`) VALUES (%i, %s, %s)', User::$id, 'default_3dmodel', $this->_post['modelrace']. ',' . $this->_post['modelgender'])) return Lang::main('genericError'); if (!setcookie('default_3dmodel', $this->_post['modelrace']. ',' . $this->_post['modelgender'], 0, '/')) return Lang::main('intError'); // int > number of edited rows > no changes is still success - if (!is_int(DB::Aowow()->query('UPDATE ?_account SET `debug` = ?d WHERE `id` = ?d', $this->_post['idsInLists'] ? 1 : 0, User::$id))) + if (!is_int(DB::Aowow()->qry('UPDATE ::account SET `debug` = %i WHERE `id` = %i', $this->_post['idsInLists'] ? 1 : 0, User::$id))) return Lang::main('intError'); $this->success = true; diff --git a/endpoints/account/update-password.php b/endpoints/account/update-password.php index 04916542..8038f8be 100644 --- a/endpoints/account/update-password.php +++ b/endpoints/account/update-password.php @@ -53,7 +53,7 @@ class AccountUpdatepasswordResponse extends TextResponse if ($this->_post['newPassword'] !== $this->_post['confirmPassword']) return Lang::account('passMismatch'); - $userData = DB::Aowow()->selectRow('SELECT `status`, `passHash`, `statusTimer` FROM ?_account WHERE `id` = ?d', User::$id); + $userData = DB::Aowow()->selectRow('SELECT `status`, `passHash`, `statusTimer` FROM ::account WHERE `id` = %i', User::$id); if ($userData['status'] != ACC_STATUS_NONE && $userData['status'] != ACC_STATUS_CHANGE_PASS && $userData['statusTimer'] > time()) return Lang::account('inputbox', 'error', 'isRecovering', [DateTime::formatTimeElapsedFloat(Cfg::get('ACC_RECOVERY_DECAY') * 1000)]); @@ -66,17 +66,17 @@ class AccountUpdatepasswordResponse extends TextResponse $token = Util::createHash(); // store new hash in updateValue field, exchange when confirmation mail gets confirmed - if (!DB::Aowow()->query('UPDATE ?_account SET `updateValue` = ?, `status` = ?d, `statusTimer` = UNIX_TIMESTAMP() + ?d, `token` = ? WHERE `id` = ?d', + if (!DB::Aowow()->qry('UPDATE ::account SET `updateValue` = %s, `status` = %i, `statusTimer` = UNIX_TIMESTAMP() + %i, `token` = %s WHERE `id` = %i', User::hashCrypt($this->_post['newPassword']), ACC_STATUS_CHANGE_PASS, Cfg::get('ACC_RECOVERY_DECAY'), $token, User::$id)) return Lang::main('intError'); - $email = DB::Aowow()->selectCell('SELECT `email` FROM ?_account WHERE `id` = ?d', User::$id); + $email = DB::Aowow()->selectCell('SELECT `email` FROM ::account WHERE `id` = %i', User::$id); if (!Util::sendMail($email, 'update-password', [$token, $email], Cfg::get('ACC_RECOVERY_DECAY'))) return Lang::main('intError2', ['send mail']); // logout all other active sessions if ($this->_post['globalLogout']) - DB::Aowow()->query('UPDATE ?_account_sessions SET `status` = ?d, `touched` = ?d WHERE `userId` = ?d AND `sessionId` <> ? AND `status` = ?d', SESSION_FORCED_LOGOUT, time(), User::$id, session_id(), SESSION_ACTIVE); + DB::Aowow()->qry('UPDATE ::account_sessions SET `status` = %i, `touched` = %i WHERE `userId` = %i AND `sessionId` <> ? AND `status` = %i', SESSION_FORCED_LOGOUT, time(), User::$id, session_id(), SESSION_ACTIVE); $this->success = true; return Lang::account('updateMessage', 'personal', [User::$email]); diff --git a/endpoints/account/update-username.php b/endpoints/account/update-username.php index 240e1542..7876d605 100644 --- a/endpoints/account/update-username.php +++ b/endpoints/account/update-username.php @@ -44,14 +44,14 @@ class AccountUpdateusernameResponse extends TextResponse if (!$this->assertPOST('newUsername')) return Lang::main('intError'); - if (DB::Aowow()->selectCell('SELECT `renameCooldown` FROM ?_account WHERE `id` = ?d', User::$id) > time()) + if (DB::Aowow()->selectCell('SELECT `renameCooldown` FROM ::account WHERE `id` = %i', User::$id) > time()) return Lang::main('intError'); // should have grabbed the error response.. // yes, including your current name. you don't want to change into your current name, right? - if (DB::Aowow()->selectCell('SELECT 1 FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_post['newUsername'])) + if (DB::Aowow()->selectCell('SELECT 1 FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_post['newUsername'])) return Lang::account('nameInUse'); - DB::Aowow()->query('UPDATE ?_account SET `username` = ?, `renameCooldown` = ?d WHERE `id` = ?d', $this->_post['newUsername'], time() + Cfg::get('acc_rename_decay'), User::$id); + DB::Aowow()->qry('UPDATE ::account SET `username` = %s, `renameCooldown` = %i WHERE `id` = %i', $this->_post['newUsername'], time() + Cfg::get('acc_rename_decay'), User::$id); $this->success = true; return Lang::account('updateMessage', 'username', [User::$username, $this->_post['newUsername']]); diff --git a/endpoints/account/weightscales.php b/endpoints/account/weightscales.php index d4bf016c..8bae7835 100644 --- a/endpoints/account/weightscales.php +++ b/endpoints/account/weightscales.php @@ -46,11 +46,11 @@ class AccountWeightscalesResponse extends TextResponse if (!$this->assertPOST('name', 'scale')) return; - $nScales = DB::Aowow()->selectCell('SELECT COUNT(`id`) FROM ?_account_weightscales WHERE `userId` = ?d', User::$id); + $nScales = DB::Aowow()->selectCell('SELECT COUNT(`id`) FROM ::account_weightscales WHERE `userId` = %i', User::$id); if ($nScales >= self::MAX_SCALES) return; - if ($id = DB::Aowow()->query('INSERT INTO ?_account_weightscales (`userId`, `name`) VALUES (?d, ?)', User::$id, $this->_post['name'])) + if ($id = DB::Aowow()->qry('INSERT INTO ::account_weightscales (`userId`, `name`) VALUES (%i, %s)', User::$id, $this->_post['name'])) if ($this->storeScaleData($id)) $this->result = $id; } @@ -61,13 +61,13 @@ class AccountWeightscalesResponse extends TextResponse return; // not in DB or not owned by user - if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_account_weightscales WHERE `userId` = ?d AND `id` = ?d', User::$id, $this->_post['id'])) + if (!DB::Aowow()->selectCell('SELECT 1 FROM ::account_weightscales WHERE `userId` = %i AND `id` = %i', User::$id, $this->_post['id'])) { trigger_error('AccountWeightscalesResponse::updateWeights - scale #'.$this->_post['id'].' not in db or not owned by user #'.User::$id, E_USER_ERROR); return; } - DB::Aowow()->query('UPDATE ?_account_weightscales SET `name` = ? WHERE `id` = ?d', $this->_post['name'], $this->_post['id']); + DB::Aowow()->qry('UPDATE ::account_weightscales SET `name` = %s WHERE `id` = %i', $this->_post['name'], $this->_post['id']); $this->storeScaleData($this->_post['id']); // return edited id on success @@ -77,20 +77,24 @@ class AccountWeightscalesResponse extends TextResponse private function deleteWeights() : void { if ($this->assertPOST('id')) - DB::Aowow()->query('DELETE FROM ?_account_weightscales WHERE `id` = ?d AND `userId` = ?d', $this->_post['id'], User::$id); + DB::Aowow()->qry('DELETE FROM ::account_weightscales WHERE `id` = %i AND `userId` = %i', $this->_post['id'], User::$id); $this->result = ''; } private function storeScaleData(int $scaleId) : bool { - if (!is_int(DB::Aowow()->query('DELETE FROM ?_account_weightscale_data WHERE `id` = ?d', $scaleId))) + if (!is_int(DB::Aowow()->qry('DELETE FROM ::account_weightscale_data WHERE `id` = %i', $scaleId))) return false; - foreach ($this->_post['scale'] as [$k, $v]) - if (Stat::getWeightJson($k)) // $v is known to be a positive int due to regex check - if (!is_int(DB::Aowow()->query('INSERT INTO ?_account_weightscale_data VALUES (?d, ?, ?d)', $scaleId, $k, $v))) - return false; + // $x['val'] is known to be a positive int due to regex check + $scaleData = array_filter($this->_post['scale'], fn($x) => Stat::getWeightJson($x['field']) && $x['val'] > 0); + + array_walk($scaleData, fn(&$x) => $x['id'] = $scaleId); + + foreach ($scaleData as $sd) + if (is_null(DB::Aowow()->qry('INSERT INTO ::account_weightscale_data %v', $sd))) + return false; return true; } @@ -103,7 +107,7 @@ class AccountWeightscalesResponse extends TextResponse protected static function checkScale(string $val) : array { if (preg_match('/^((\w+:\d+)(,\w+:\d+)*)$/', $val)) - return array_map(fn($x) => explode(':', $x), explode(',', $val)); + return array_map(fn($x) => array_combine(['field', 'val'], explode(':', $x)), explode(',', $val)); return []; } diff --git a/endpoints/achievement/achievement.php b/endpoints/achievement/achievement.php index 5a5eeb01..6c63fd11 100644 --- a/endpoints/achievement/achievement.php +++ b/endpoints/achievement/achievement.php @@ -73,7 +73,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache while ($curCat > 0) { $catPath[] = $curCat; - $curCat = DB::Aowow()->SelectCell('SELECT `parentCat` FROM ?_achievementcategory WHERE `id` = ?d', $curCat); + $curCat = DB::Aowow()->SelectCell('SELECT `parentCat` FROM ::achievementcategory WHERE `id` = %i', $curCat); } $this->breadcrumb = array_merge($this->breadcrumb, array_reverse($catPath)); @@ -120,8 +120,8 @@ class AchievementBaseResponse extends TemplateResponse implements ICache // profiler relateed (note that this is part of the cache. I don't think this is important enough to calc for every view) 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 `custom` = 0 AND `stub` = 0'); + $x = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ::profiler_completion_achievements WHERE `achievementId` = %i', $this->typeId); + $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 @@ -207,7 +207,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache $this->rewards = [$rewItems, $rewTitles, $text]; // factionchange-equivalent - if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = ?d, `alliance_id`, -`horde_id`) FROM player_factionchange_achievement WHERE `alliance_id` = ?d OR `horde_id` = ?d', $this->typeId, $this->typeId, $this->typeId)) + if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = %i, `alliance_id`, -`horde_id`) FROM player_factionchange_achievement WHERE `alliance_id` = %i OR `horde_id` = %i', $this->typeId, $this->typeId, $this->typeId)) { $altAcv = new AchievementList(array(['id', abs($pendant)])); if (!$altAcv->error) @@ -230,7 +230,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache // serverside extra-Data (not sure why ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE is set, let a lone a couple hundred times) if ($crtIds = array_column($this->subject->getCriteria(), 'id')) - $crtExtraData = DB::World()->select('SELECT `criteria_id` AS ARRAY_KEY, `type` AS ARRAY_KEY2, `value1`, `value2`, `ScriptName` FROM achievement_criteria_data WHERE `type` <> ?d AND `criteria_id` IN (?a)', ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE, $crtIds); + $crtExtraData = DB::World()->selectAssoc('SELECT `criteria_id` AS ARRAY_KEY, `type` AS ARRAY_KEY2, `value1`, `value2`, `ScriptName` FROM achievement_criteria_data WHERE `type` <> %i AND `criteria_id` IN %in', ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE, $crtIds); else $crtExtraData = []; @@ -261,7 +261,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: - $zoneId = DB::Aowow()->selectCell('SELECT `id` FROM ?_zones WHERE `mapId` = ?', $obj); + $zoneId = DB::Aowow()->selectCell('SELECT `id` FROM ::zones WHERE `mapId` = %s', $obj); $crtIcon = new IconElement(Type::ZONE, $zoneId ?: 0, $crtName ?: ZoneList::getName($zoneId), size: IconElement::SIZE_SMALL, element: 'iconlist-icon'); break; // link to area @@ -423,7 +423,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache } // tab: criteria of - $refs = DB::Aowow()->SelectCol('SELECT `refAchievementId` FROM ?_achievementcriteria WHERE `type` = ?d AND `value1` = ?d', + $refs = DB::Aowow()->SelectCol('SELECT `refAchievementId` FROM ::achievementcriteria WHERE `type` = %i AND `value1` = %i', ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, $this->typeId ); @@ -463,7 +463,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache { if ($_ = $this->subject->getField('mailTemplate')) { - $letter = DB::Aowow()->selectRow('SELECT * FROM ?_mails WHERE `id` = ?d', $_); + $letter = DB::Aowow()->selectRow('SELECT * FROM ::mails WHERE `id` = %i', $_); if (!$letter) return false; @@ -502,7 +502,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache $avlb = []; foreach (Profiler::getRealms() AS $rId => $rData) - if (!DB::Characters($rId)->selectCell('SELECT 1 FROM character_achievement WHERE `achievement` = ?d', $pt->typeId)) + if (!DB::Characters($rId)->selectCell('SELECT 1 FROM character_achievement WHERE `achievement` = %i', $pt->typeId)) $avlb[] = Util::ucWords($rData['name']); if (!$avlb) diff --git a/endpoints/achievements/achievements.php b/endpoints/achievements/achievements.php index 3a934e4e..6597306f 100644 --- a/endpoints/achievements/achievements.php +++ b/endpoints/achievements/achievements.php @@ -123,7 +123,7 @@ class AchievementsBaseResponse extends TemplateResponse implements ICache $conditions = [Listview::DEFAULT_SIZE]; if ($fiCnd) $conditions[] = $fiCnd; - if ($catList = DB::Aowow()->SelectCol('SELECT `id` FROM ?_achievementcategory WHERE `parentCat` IN (?a) OR `parentCat2` IN (?a) ', $this->category, $this->category)) + if ($catList = DB::Aowow()->SelectCol('SELECT `id` FROM ::achievementcategory WHERE `parentCat` IN %in OR `parentCat2` IN %in ', $this->category, $this->category)) $conditions[] = ['category', $catList]; $acvList = new AchievementList($conditions, ['calcTotal' => true]); diff --git a/endpoints/admin/announcements.php b/endpoints/admin/announcements.php index ccd92eb7..b1fdc774 100644 --- a/endpoints/admin/announcements.php +++ b/endpoints/admin/announcements.php @@ -44,13 +44,13 @@ class AdminAnnouncementsResponse extends TemplateResponse return; } - if (!DB::Aowow()->selectCell('SELECT 1 FROM ?_announcements WHERE `id` = ?d', $this->_get['id'])) + if (!DB::Aowow()->selectCell('SELECT 1 FROM ::announcements WHERE `id` = %i', $this->_get['id'])) { trigger_error('AdminAnnouncementsResponse::updateStatus - announcement does not exist'); return; } - DB::Aowow()->query('UPDATE ?_announcements SET `status` = ?d WHERE `id` = ?d', $this->_get['status'], $this->_get['id']); + DB::Aowow()->qry('UPDATE ::announcements SET `status` = %i WHERE `id` = %i', $this->_get['status'], $this->_get['id']); } private function displayEditor() : void diff --git a/endpoints/admin/comment.php b/endpoints/admin/comment.php index 08d4f8ba..26b78e29 100644 --- a/endpoints/admin/comment.php +++ b/endpoints/admin/comment.php @@ -33,13 +33,13 @@ class AdminCommentResponse extends TextResponse $ok = false; if ($this->_post['status']) // outdated, mark as deleted and clear other flags (sticky + outdated) { - if ($ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = ?d, `deleteUserId` = ?d, `deleteDate` = ?d WHERE `id` = ?d', CC_FLAG_DELETED, User::$id, time(), $this->_post['id'])) + if ($ok = DB::Aowow()->qry('UPDATE ::comments SET `flags` = %i, `deleteUserId` = %i, `deleteDate` = %i WHERE `id` = %i', CC_FLAG_DELETED, User::$id, time(), $this->_post['id'])) if ($rep = new Report(Report::MODE_COMMENT, Report::CO_OUT_OF_DATE, $this->_post['id'])) $rep->close(Report::STATUS_CLOSED_SOLVED); } else // up to date { - if ($ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` & ~?d WHERE `id` = ?d', CC_FLAG_OUTDATED, $this->_post['id'])) + if ($ok = DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` & ~%i WHERE `id` = %i', CC_FLAG_OUTDATED, $this->_post['id'])) if ($rep = new Report(Report::MODE_COMMENT, Report::CO_OUT_OF_DATE, $this->_post['id'])) $rep->close(Report::STATUS_CLOSED_WONTFIX); } diff --git a/endpoints/admin/guide.php b/endpoints/admin/guide.php index 8a6d93d8..90ee553e 100644 --- a/endpoints/admin/guide.php +++ b/endpoints/admin/guide.php @@ -31,7 +31,7 @@ class AdminGuideResponse extends TextResponse return; } - $guide = DB::Aowow()->selectRow('SELECT `userId`, `status` FROM ?_guides WHERE `id` = ?d', $this->_post['id']); + $guide = DB::Aowow()->selectRow('SELECT `userId`, `status` FROM ::guides WHERE `id` = %i', $this->_post['id']); if (!$guide) { trigger_error('AdminGuideResponse - guide #'.$this->_post['id'].' not found', E_USER_ERROR); @@ -63,16 +63,16 @@ class AdminGuideResponse extends TextResponse private function update(int $id, int $status, ?string $msg = null) : bool { if ($status == GuideMgr::STATUS_APPROVED) // set display rev to latest - $ok = DB::Aowow()->query('UPDATE ?_guides SET `status` = ?d, `rev` = (SELECT `rev` FROM ?_articles WHERE `type` = ?d AND `typeId` = ?d ORDER BY `rev` DESC LIMIT 1), `approveUserId` = ?d, `approveDate` = ?d WHERE `id` = ?d', $status, Type::GUIDE, $id, User::$id, time(), $id); + $ok = DB::Aowow()->qry('UPDATE ::guides SET `status` = %i, `rev` = (SELECT `rev` FROM ::articles WHERE `type` = %i AND `typeId` = %i ORDER BY `rev` DESC LIMIT 1), `approveUserId` = %i, `approveDate` = %i WHERE `id` = %i', $status, Type::GUIDE, $id, User::$id, time(), $id); else - $ok = DB::Aowow()->query('UPDATE ?_guides SET `status` = ?d WHERE `id` = ?d', $status, $id); + $ok = DB::Aowow()->qry('UPDATE ::guides SET `status` = %i WHERE `id` = %i', $status, $id); if (!$ok) return false; - DB::Aowow()->query('INSERT INTO ?_guides_changelog (`id`, `date`, `userId`, `status`) VALUES (?d, ?d, ?d, ?d)', $id, time(), User::$id, $status); + DB::Aowow()->qry('INSERT INTO ::guides_changelog (`id`, `date`, `userId`, `status`) VALUES (%i, %i, %i, %i)', $id, time(), User::$id, $status); if ($msg) - DB::Aowow()->query('INSERT INTO ?_guides_changelog (`id`, `date`, `userId`, `msg`) VALUES (?d, ?d, ?d, ?)', $id, time(), User::$id, $msg); + DB::Aowow()->qry('INSERT INTO ::guides_changelog (`id`, `date`, `userId`, `msg`) VALUES (%i, %i, %i, %s)', $id, time(), User::$id, $msg); return true; } diff --git a/endpoints/admin/guides.php b/endpoints/admin/guides.php index 16aa460b..26d6f844 100644 --- a/endpoints/admin/guides.php +++ b/endpoints/admin/guides.php @@ -30,7 +30,7 @@ class AdminGuidesResponse extends TemplateResponse else { $data = $pending->getListviewData(); - $latest = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, MAX(`rev`) FROM ?_articles WHERE `type` = ?d AND `typeId` IN (?a) GROUP BY `rev`', Type::GUIDE, $pending->getFoundIDs()); + $latest = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, MAX(`rev`) FROM ::articles WHERE `type` = %i AND `typeId` IN %in GROUP BY `rev`', Type::GUIDE, $pending->getFoundIDs()); foreach ($latest as $id => $rev) $data[$id]['rev'] = $rev; } diff --git a/endpoints/admin/screenshots.php b/endpoints/admin/screenshots.php index 33fe5a21..c8b87ba8 100644 --- a/endpoints/admin/screenshots.php +++ b/endpoints/admin/screenshots.php @@ -52,7 +52,7 @@ class AdminScreenshotsResponse extends TemplateResponse else if ($this->_get['user']) { if (mb_strlen($this->_get['user']) >= 3) - if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user'])) + if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user'])) $ssData = ScreenshotMgr::getScreenshots(userId: $uId, nFound: $nMatches); } else diff --git a/endpoints/admin/screenshots_approve.php b/endpoints/admin/screenshots_approve.php index f2f3b5dd..5bb528c2 100644 --- a/endpoints/admin/screenshots_approve.php +++ b/endpoints/admin/screenshots_approve.php @@ -25,7 +25,7 @@ class AdminScreenshotsActionApproveResponse extends TextResponse ScreenshotMgr::init(); // create resized and thumb version of screenshot - $ssEntries = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId` FROM ?_screenshots WHERE (`status` & ?d) = 0 AND `id` IN (?a)', CC_FLAG_APPROVED, $this->_get['id']); + $ssEntries = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId` FROM ::screenshots WHERE (`status` & %i) = 0 AND `id` IN %in', CC_FLAG_APPROVED, $this->_get['id']); foreach ($ssEntries as $id => $ssData) { if (!ScreenshotMgr::loadFile(ScreenshotMgr::PATH_PENDING, $id)) @@ -42,14 +42,14 @@ class AdminScreenshotsActionApproveResponse extends TextResponse continue; // set as approved in DB - DB::Aowow()->query('UPDATE ?_screenshots SET `status` = ?d, `userIdApprove` = ?d WHERE `id` = ?d', CC_FLAG_APPROVED, User::$id, $id); + DB::Aowow()->qry('UPDATE ::screenshots SET `status` = %i, `userIdApprove` = %i WHERE `id` = %i', CC_FLAG_APPROVED, User::$id, $id); // gain siterep Util::gainSiteReputation($ssData['userIdOwner'], SITEREP_ACTION_SUBMIT_SCREENSHOT, ['id' => $id, 'what' => 1, 'date' => $ssData['date']]); // flag DB entry as having screenshots if ($tbl = Type::getClassAttrib($ssData['type'], 'dataTable')) - DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_SCREENSHOT, $ssData['typeId']); + DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_SCREENSHOT, $ssData['typeId']); unset($ssEntries[$id]); } diff --git a/endpoints/admin/screenshots_delete.php b/endpoints/admin/screenshots_delete.php index 402bc0ec..bd61a07c 100644 --- a/endpoints/admin/screenshots_delete.php +++ b/endpoints/admin/screenshots_delete.php @@ -26,9 +26,9 @@ class AdminScreenshotsActionDeleteResponse extends TextResponse foreach ($this->_get['id'] as $id) { // irrevocably purge files already flagged as deleted (should only exist as pending) - if (User::isInGroup(U_GROUP_ADMIN) && DB::Aowow()->selectCell('SELECT 1 FROM ?_screenshots WHERE `status` & ?d AND `id` = ?d', CC_FLAG_DELETED, $id)) + if (User::isInGroup(U_GROUP_ADMIN) && DB::Aowow()->selectCell('SELECT 1 FROM ::screenshots WHERE `status` & %i AND `id` = %i', CC_FLAG_DELETED, $id)) { - DB::Aowow()->query('DELETE FROM ?_screenshots WHERE `id` = ?d', $id); + DB::Aowow()->qry('DELETE FROM ::screenshots WHERE `id` = %i', $id); if (file_exists(sprintf(ScreenshotMgr::PATH_PENDING, $id))) unlink(sprintf(ScreenshotMgr::PATH_PENDING, $id)); @@ -47,16 +47,16 @@ class AdminScreenshotsActionDeleteResponse extends TextResponse } // flag as deleted if not aready - $oldEntries = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, GROUP_CONCAT(`typeId`) FROM ?_screenshots WHERE `id` IN (?a) GROUP BY `type`', $this->_get['id']); - DB::Aowow()->query('UPDATE ?_screenshots SET `status` = ?d, `userIdDelete` = ?d WHERE `id` IN (?a)', CC_FLAG_DELETED, User::$id, $this->_get['id']); + $oldEntries = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, GROUP_CONCAT(`typeId`) FROM ::screenshots WHERE `id` IN %in GROUP BY `type`', $this->_get['id']); + DB::Aowow()->qry('UPDATE ::screenshots SET `status` = %i, `userIdDelete` = %i WHERE `id` IN %in', CC_FLAG_DELETED, User::$id, $this->_get['id']); // deflag db entry as having screenshots foreach ($oldEntries as $type => $typeIds) { $typeIds = explode(',', $typeIds); - $toUnflag = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(BIT_OR(`status`) & ?d, 1, 0) AS "hasMore" FROM ?_screenshots WHERE `type` = ?d AND `typeId` IN (?a) GROUP BY `typeId` HAVING `hasMore` = 0', CC_FLAG_APPROVED, $type, $typeIds); + $toUnflag = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(BIT_OR(`status`) & %i, 1, 0) AS "hasMore" FROM ::screenshots WHERE `type` = %i AND `typeId` IN %in GROUP BY `typeId` HAVING `hasMore` = 0', CC_FLAG_APPROVED, $type, $typeIds); if ($toUnflag && ($tbl = Type::getClassAttrib($type, 'dataTable'))) - DB::Aowow()->query('UPDATE ?# SET cuFlags = cuFlags & ~?d WHERE id IN (?a)', $tbl, CUSTOM_HAS_SCREENSHOT, array_keys($toUnflag)); + DB::Aowow()->qry('UPDATE %n SET cuFlags = cuFlags & ~%i WHERE id IN %in', $tbl, CUSTOM_HAS_SCREENSHOT, array_keys($toUnflag)); } } } diff --git a/endpoints/admin/screenshots_editalt.php b/endpoints/admin/screenshots_editalt.php index 0c5feee4..2dca89cc 100644 --- a/endpoints/admin/screenshots_editalt.php +++ b/endpoints/admin/screenshots_editalt.php @@ -24,7 +24,7 @@ class AdminScreenshotsActionEditaltResponse extends TextResponse if (!$this->assertGET('id')) return; - DB::Aowow()->query('UPDATE ?_screenshots SET `caption` = ? WHERE `id` = ?d', + DB::Aowow()->qry('UPDATE ::screenshots SET `caption` = %s WHERE `id` = %i', $this->handleCaption($this->_post['alt']), $this->_get['id'] ); diff --git a/endpoints/admin/screenshots_manage.php b/endpoints/admin/screenshots_manage.php index eddd0d92..752469d1 100644 --- a/endpoints/admin/screenshots_manage.php +++ b/endpoints/admin/screenshots_manage.php @@ -23,7 +23,7 @@ class AdminScreenshotsActionManageResponse extends TextResponse if ($this->_get['type'] && $this->_get['typeid']) $res = ScreenshotMgr::getScreenshots($this->_get['type'], $this->_get['typeid']); else if ($this->_get['user']) - if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user'])) + if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user'])) $res = ScreenshotMgr::getScreenshots(userId: $uId); $this->result = 'ssm_screenshotData = '.Util::toJSON($res); diff --git a/endpoints/admin/screenshots_relocate.php b/endpoints/admin/screenshots_relocate.php index 3f387fb7..03fd0d5d 100644 --- a/endpoints/admin/screenshots_relocate.php +++ b/endpoints/admin/screenshots_relocate.php @@ -24,7 +24,7 @@ class AdminScreenshotsActionRelocateResponse extends TextResponse return; } - [$type, $oldTypeId] = array_values(DB::Aowow()->selectRow('SELECT `type`, `typeId` FROM ?_screenshots WHERE `id` = ?d', $this->_get['id'])); + [$type, $oldTypeId] = array_values(DB::Aowow()->selectRow('SELECT `type`, `typeId` FROM ::screenshots WHERE `id` = %i', $this->_get['id'])); $typeId = $this->_get['typeid']; if (Type::validateIds($type, $typeId)) @@ -32,15 +32,15 @@ class AdminScreenshotsActionRelocateResponse extends TextResponse $tbl = Type::getClassAttrib($type, 'dataTable'); // move screenshot - DB::Aowow()->query('UPDATE ?_screenshots SET `typeId` = ?d WHERE `id` = ?d', $typeId, $this->_get['id']); + DB::Aowow()->qry('UPDATE ::screenshots SET `typeId` = %i WHERE `id` = %i', $typeId, $this->_get['id']); // flag target as having screenshot - DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_SCREENSHOT, $typeId); + DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_SCREENSHOT, $typeId); // deflag source for having had screenshots (maybe) - $ssInfo = DB::Aowow()->selectRow('SELECT IF(BIT_OR(~`status`) & ?d, 1, 0) AS "hasMore" FROM ?_screenshots WHERE `status`& ?d AND `type` = ?d AND `typeId` = ?d', CC_FLAG_DELETED, CC_FLAG_APPROVED, $type, $oldTypeId); + $ssInfo = DB::Aowow()->selectRow('SELECT IF(BIT_OR(~`status`) & %i, 1, 0) AS "hasMore" FROM ::screenshots WHERE `status`& %i AND `type` = %i AND `typeId` = %i', CC_FLAG_DELETED, CC_FLAG_APPROVED, $type, $oldTypeId); if ($ssInfo || !$ssInfo['hasMore']) - DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` & ~?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_SCREENSHOT, $oldTypeId); + DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` & ~%i WHERE `id` = %i', $tbl, CUSTOM_HAS_SCREENSHOT, $oldTypeId); } else trigger_error('AdminScreenshotsActionRelocateResponse - invalid typeId #'.$typeId.' for type #'.$type, E_USER_ERROR); diff --git a/endpoints/admin/screenshots_sticky.php b/endpoints/admin/screenshots_sticky.php index 26e3235f..d95ac874 100644 --- a/endpoints/admin/screenshots_sticky.php +++ b/endpoints/admin/screenshots_sticky.php @@ -25,7 +25,7 @@ class AdminScreenshotsActionStickyResponse extends TextResponse // this one is a bit strange: as far as i've seen, the only thing a 'sticky' screenshot does is show up in the infobox // this also means, that only one screenshot per page should be sticky // so, handle it one by one and the last one affecting one particular type/typId-key gets the cake - $ssEntries = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId`, `status` FROM ?_screenshots WHERE (`status` & ?d) = 0 AND `id` IN (?a)', CC_FLAG_DELETED, $this->_get['id']); + $ssEntries = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId`, `status` FROM ::screenshots WHERE (`status` & %i) = 0 AND `id` IN %in', CC_FLAG_DELETED, $this->_get['id']); foreach ($ssEntries as $id => $ssData) { // approve yet unapproved screenshots @@ -47,21 +47,21 @@ class AdminScreenshotsActionStickyResponse extends TextResponse continue; // set as approved in DB - DB::Aowow()->query('UPDATE ?_screenshots SET `status` = ?d, `userIdApprove` = ?d WHERE `id` = ?d', CC_FLAG_APPROVED, User::$id, $id); + DB::Aowow()->qry('UPDATE ::screenshots SET `status` = %i, `userIdApprove` = %i WHERE `id` = %i', CC_FLAG_APPROVED, User::$id, $id); // gain siterep Util::gainSiteReputation($ssData['userIdOwner'], SITEREP_ACTION_SUBMIT_SCREENSHOT, ['id' => $id, 'what' => 1, 'date' => $ssData['date']]); // flag DB entry as having screenshots if ($tbl = Type::getClassAttrib($ssData['type'], 'dataTable')) - DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_SCREENSHOT, $ssData['typeId']); + DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_SCREENSHOT, $ssData['typeId']); } // reset all others - DB::Aowow()->query('UPDATE ?_screenshots a, ?_screenshots b SET a.`status` = a.`status` & ~?d WHERE a.`type` = b.`type` AND a.`typeId` = b.`typeId` AND a.`id` <> b.`id` AND b.`id` = ?d', CC_FLAG_STICKY, $id); + DB::Aowow()->qry('UPDATE ::screenshots a, ::screenshots b SET a.`status` = a.`status` & ~%i WHERE a.`type` = b.`type` AND a.`typeId` = b.`typeId` AND a.`id` <> b.`id` AND b.`id` = %i', CC_FLAG_STICKY, $id); // toggle sticky status - DB::Aowow()->query('UPDATE ?_screenshots SET `status` = IF(`status` & ?d, `status` & ~?d, `status` | ?d) WHERE `id` = ?d AND `status` & ?d', CC_FLAG_STICKY, CC_FLAG_STICKY, CC_FLAG_STICKY, $id, CC_FLAG_APPROVED); + DB::Aowow()->qry('UPDATE ::screenshots SET `status` = IF(`status` & %i, `status` & ~%i, `status` | %i) WHERE `id` = %i AND `status` & %i', CC_FLAG_STICKY, CC_FLAG_STICKY, CC_FLAG_STICKY, $id, CC_FLAG_APPROVED); unset($ssEntries[$id]); } diff --git a/endpoints/admin/spawn-override.php b/endpoints/admin/spawn-override.php index 49bb1029..8b6931ab 100644 --- a/endpoints/admin/spawn-override.php +++ b/endpoints/admin/spawn-override.php @@ -45,7 +45,7 @@ class AdminSpawnoverrideResponse extends TextResponse return; } - DB::Aowow()->query('REPLACE INTO ?_spawns_override (`type`, `typeGuid`, `areaId`, `floor`, `revision`) VALUES (?d, ?d, ?d, ?d, ?d)', $type, $guid, $area, $floor, AOWOW_REVISION); + DB::Aowow()->qry('REPLACE INTO ::spawns_override (`type`, `typeGuid`, `areaId`, `floor`, `revision`) VALUES (%i, %i, %i, %i, %i)', $type, $guid, $area, $floor, AOWOW_REVISION); $wPos = WorldPosition::getForGUID($type, $guid); if (!$wPos) @@ -72,7 +72,7 @@ class AdminSpawnoverrideResponse extends TextResponse // if creature try for waypoints if ($type == Type::NPC) { - if ($swp = DB::World()->select('SELECT -w.`id` AS "entry", w.`point` AS "pointId", w.`position_x` AS "posX", w.`position_y` AS "posY" FROM creature_addon ca JOIN waypoint_data w ON w.`id` = ca.`path_id` WHERE ca.`guid` = ?d AND ca.`path_id` <> 0', $guid)) + if ($swp = DB::World()->selectAssoc('SELECT -w.`id` AS "entry", w.`point` AS "pointId", w.`position_x` AS "posX", w.`position_y` AS "posY" FROM creature_addon ca JOIN waypoint_data w ON w.`id` = ca.`path_id` WHERE ca.`guid` = %i AND ca.`path_id` <> 0', $guid)) { foreach ($swp as $w) { @@ -85,17 +85,17 @@ class AdminSpawnoverrideResponse extends TextResponse 'floor' => $point[0]['floor'] ); - DB::Aowow()->query('UPDATE ?_creature_waypoints SET ?a WHERE `creatureOrPath` = ?d AND `point` = ?d', $p, $w['entry'], $w['pointId']); + DB::Aowow()->qry('UPDATE ::creature_waypoints SET %a WHERE `creatureOrPath` = %i AND `point` = %i', $p, $w['entry'], $w['pointId']); } } } // also move linked vehicle accessories (on the very same position) - $updGUIDs = array_merge($updGUIDs, DB::Aowow()->selectCol('SELECT s2.`guid` FROM ?_spawns s1 JOIN ?_spawns s2 ON s1.`posX` = s2.`posX` AND s1.`posY` = s2.`posY` AND - s1.`areaId` = s2.`areaId` AND s1.`floor` = s2.`floor` AND s2.`guid` < 0 WHERE s1.`guid` = ?d', $guid)); + $updGUIDs = array_merge($updGUIDs, DB::Aowow()->selectCol('SELECT s2.`guid` FROM ::spawns s1 JOIN ::spawns s2 ON s1.`posX` = s2.`posX` AND s1.`posY` = s2.`posY` AND + s1.`areaId` = s2.`areaId` AND s1.`floor` = s2.`floor` AND s2.`guid` < 0 WHERE s1.`guid` = %i', $guid)); } - if (DB::Aowow()->query('UPDATE ?_spawns SET ?a WHERE `type` = ?d AND `guid` IN (?a)', $newPos, $type, $updGUIDs)) + if (DB::Aowow()->qry('UPDATE ::spawns SET %a WHERE `type` = %i AND `guid` IN %in', $newPos, $type, $updGUIDs)) $this->result = self::ERR_NONE; else $this->result = self::ERR_WRITE_DB; diff --git a/endpoints/admin/videos.php b/endpoints/admin/videos.php index 10beece8..04956306 100644 --- a/endpoints/admin/videos.php +++ b/endpoints/admin/videos.php @@ -52,7 +52,7 @@ class AdminVideosResponse extends TemplateResponse else if ($this->_get['user']) { if (mb_strlen($this->_get['user']) >= 3) - if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user'])) + if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user'])) $viData = VideoMgr::getVideos(userId: $uId, nFound: $nMatches); } else diff --git a/endpoints/admin/videos_approve.php b/endpoints/admin/videos_approve.php index 51dfe1d0..efa12210 100644 --- a/endpoints/admin/videos_approve.php +++ b/endpoints/admin/videos_approve.php @@ -22,18 +22,18 @@ class AdminVideosActionApproveResponse extends TextResponse return; } - $viEntries = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId` FROM ?_videos WHERE (`status` & ?d) = 0 AND `id` IN (?a)', CC_FLAG_APPROVED, $this->_get['id']); + $viEntries = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId` FROM ::videos WHERE (`status` & %i) = 0 AND `id` IN %in', CC_FLAG_APPROVED, $this->_get['id']); foreach ($viEntries as $id => $viData) { // set as approved in DB - DB::Aowow()->query('UPDATE ?_videos SET `status` = ?d, `userIdApprove` = ?d WHERE `id` = ?d', CC_FLAG_APPROVED, User::$id, $id); + DB::Aowow()->qry('UPDATE ::videos SET `status` = %i, `userIdApprove` = %i WHERE `id` = %i', CC_FLAG_APPROVED, User::$id, $id); // gain siterep Util::gainSiteReputation($viData['userIdOwner'], SITEREP_ACTION_SUGGEST_VIDEO, ['id' => $id, 'what' => 1, 'date' => $viData['date']]); // flag DB entry as having videos if ($tbl = Type::getClassAttrib($viData['type'], 'dataTable')) - DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_VIDEO, $viData['typeId']); + DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_VIDEO, $viData['typeId']); unset($viEntries[$id]); } diff --git a/endpoints/admin/videos_delete.php b/endpoints/admin/videos_delete.php index d3b6c19e..7a404124 100644 --- a/endpoints/admin/videos_delete.php +++ b/endpoints/admin/videos_delete.php @@ -25,19 +25,19 @@ class AdminVideosActionDeleteResponse extends TextResponse // irrevocably purge files already flagged as deleted (should only exist as pending) if (User::isInGroup(U_GROUP_ADMIN)) - DB::Aowow()->selectCell('SELECT 1 FROM ?_videos WHERE `status` & ?d AND `id` IN (?a)', CC_FLAG_DELETED, $this->_get['id']); + DB::Aowow()->selectCell('SELECT 1 FROM ::videos WHERE `status` & %i AND `id` IN %in', CC_FLAG_DELETED, $this->_get['id']); // flag as deleted if not aready - $oldEntries = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, GROUP_CONCAT(`typeId`) FROM ?_videos WHERE `id` IN (?a) GROUP BY `type`', $this->_get['id']); - DB::Aowow()->query('UPDATE ?_videos SET `status` = ?d, `userIdDelete` = ?d WHERE (`status` & ?d) = 0 AND `id` IN (?a)', CC_FLAG_DELETED, User::$id, CC_FLAG_DELETED, $this->_get['id']); + $oldEntries = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, GROUP_CONCAT(`typeId`) FROM ::videos WHERE `id` IN %in GROUP BY `type`', $this->_get['id']); + DB::Aowow()->qry('UPDATE ::videos SET `status` = %i, `userIdDelete` = %i WHERE (`status` & %i) = 0 AND `id` IN %in', CC_FLAG_DELETED, User::$id, CC_FLAG_DELETED, $this->_get['id']); // deflag db entry as having videos foreach ($oldEntries as $type => $typeIds) { $typeIds = explode(',', $typeIds); - $toUnflag = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(BIT_OR(`status`) & ?d, 1, 0) AS "hasMore" FROM ?_videos WHERE `type` = ?d AND `typeId` IN (?a) GROUP BY `typeId` HAVING `hasMore` = 0', CC_FLAG_APPROVED, $type, $typeIds); + $toUnflag = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(BIT_OR(`status`) & %i, 1, 0) AS "hasMore" FROM ::videos WHERE `type` = %i AND `typeId` IN %in GROUP BY `typeId` HAVING `hasMore` = 0', CC_FLAG_APPROVED, $type, $typeIds); if ($toUnflag && ($tbl = Type::getClassAttrib($type, 'dataTable'))) - DB::Aowow()->query('UPDATE ?# SET cuFlags = cuFlags & ~?d WHERE id IN (?a)', $tbl, CUSTOM_HAS_VIDEO, array_keys($toUnflag)); + DB::Aowow()->qry('UPDATE %n SET cuFlags = cuFlags & ~%i WHERE id IN %in', $tbl, CUSTOM_HAS_VIDEO, array_keys($toUnflag)); } } } diff --git a/endpoints/admin/videos_edittitle.php b/endpoints/admin/videos_edittitle.php index d9c92dfe..d6523f6d 100644 --- a/endpoints/admin/videos_edittitle.php +++ b/endpoints/admin/videos_edittitle.php @@ -26,6 +26,6 @@ class AdminVideosActionEdittitleResponse extends TextResponse $caption = $this->handleCaption($this->_post['title']); - DB::Aowow()->query('UPDATE ?_videos SET `caption` = ? WHERE `id` = ?d', $caption, $this->_get['id'][0]); + DB::Aowow()->qry('UPDATE ::videos SET `caption` = %s WHERE `id` = %i', $caption, $this->_get['id'][0]); } } diff --git a/endpoints/admin/videos_manage.php b/endpoints/admin/videos_manage.php index 0bd4e31e..fb5180f7 100644 --- a/endpoints/admin/videos_manage.php +++ b/endpoints/admin/videos_manage.php @@ -23,7 +23,7 @@ class AdminVideosActionManageResponse extends TextResponse if ($this->_get['type'] && $this->_get['typeid']) $res = VideoMgr::getVideos($this->_get['type'], $this->_get['typeid']); else if ($this->_get['user']) - if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user'])) + if ($uId = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user'])) $res = VideoMgr::getVideos(userId: $uId); $this->result = 'vim_videoData = '.Util::toJSON($res); diff --git a/endpoints/admin/videos_order.php b/endpoints/admin/videos_order.php index f11f64eb..05fd749e 100644 --- a/endpoints/admin/videos_order.php +++ b/endpoints/admin/videos_order.php @@ -25,7 +25,7 @@ class AdminVideosActionOrderResponse extends TextResponse $id = $this->_get['id'][0]; - $videos = DB::Aowow()->selectCol('SELECT a.`id` AS ARRAY_KEY, a.`pos` FROM ?_videos a, ?_videos b WHERE a.`type` = b.`type` AND a.`typeId` = b.`typeId` AND (a.`status` & ?d) = 0 AND b.`id` = ?d ORDER BY a.`pos` ASC', CC_FLAG_DELETED, $id); + $videos = DB::Aowow()->selectCol('SELECT a.`id` AS ARRAY_KEY, a.`pos` FROM ::videos a, ::videos b WHERE a.`type` = b.`type` AND a.`typeId` = b.`typeId` AND (a.`status` & %i) = 0 AND b.`id` = %i ORDER BY a.`pos` ASC', CC_FLAG_DELETED, $id); if (!$videos || count($videos) == 1) { trigger_error('AdminVideosActionOrderResponse - not enough videos to sort', E_USER_WARNING); @@ -52,6 +52,6 @@ class AdminVideosActionOrderResponse extends TextResponse $videos[$id] += $dir; foreach ($videos as $id => $pos) - DB::Aowow()->query('UPDATE ?_videos SET `pos` = ?d WHERE `id` = ?d', $pos, $id); + DB::Aowow()->qry('UPDATE ::videos SET `pos` = %i WHERE `id` = %i', $pos, $id); } } diff --git a/endpoints/admin/videos_relocate.php b/endpoints/admin/videos_relocate.php index aa2bd6a1..12230906 100644 --- a/endpoints/admin/videos_relocate.php +++ b/endpoints/admin/videos_relocate.php @@ -25,7 +25,7 @@ class AdminVideosActionRelocateResponse extends TextResponse } $id = $this->_get['id'][0]; - [$type, $oldTypeId] = array_values(DB::Aowow()->selectRow('SELECT `type`, `typeId` FROM ?_videos WHERE `id` = ?d', $id)); + [$type, $oldTypeId] = array_values(DB::Aowow()->selectRow('SELECT `type`, `typeId` FROM ::videos WHERE `id` = %i', $id)); $typeId = $this->_get['typeid']; if (Type::validateIds($type, $typeId)) @@ -33,15 +33,15 @@ class AdminVideosActionRelocateResponse extends TextResponse $tbl = Type::getClassAttrib($type, 'dataTable'); // move video - DB::Aowow()->query('UPDATE ?_videos SET `typeId` = ?d WHERE `id` = ?d', $typeId, $id); + DB::Aowow()->qry('UPDATE ::videos SET `typeId` = %i WHERE `id` = %i', $typeId, $id); // flag target as having video - DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_VIDEO, $typeId); + DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_VIDEO, $typeId); // deflag source for having had videos (maybe) - $viInfo = DB::Aowow()->selectRow('SELECT IF(BIT_OR(~`status`) & ?d, 1, 0) AS "hasMore" FROM ?_videos WHERE `status`& ?d AND `type` = ?d AND `typeId` = ?d', CC_FLAG_DELETED, CC_FLAG_APPROVED, $type, $oldTypeId); + $viInfo = DB::Aowow()->selectRow('SELECT IF(BIT_OR(~`status`) & %i, 1, 0) AS "hasMore" FROM ::videos WHERE `status`& %i AND `type` = %i AND `typeId` = %i', CC_FLAG_DELETED, CC_FLAG_APPROVED, $type, $oldTypeId); if ($viInfo || !$viInfo['hasMore']) - DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` & ~?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_VIDEO, $oldTypeId); + DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` & ~%i WHERE `id` = %i', $tbl, CUSTOM_HAS_VIDEO, $oldTypeId); } else trigger_error('AdminVideosActionRelocateResponse - invalid typeId #'.$typeId.' for type #'.$type, E_USER_ERROR); diff --git a/endpoints/admin/videos_sticky.php b/endpoints/admin/videos_sticky.php index ea79ac4b..40c537af 100644 --- a/endpoints/admin/videos_sticky.php +++ b/endpoints/admin/videos_sticky.php @@ -24,28 +24,28 @@ class AdminVideosActionStickyResponse extends TextResponse // this one is a bit strange: as far as i've seen, the only thing a 'sticky' video does is show up in the infobox // this also means, that only one video per page should be sticky // so, handle it one by one and the last one affecting one particular type/typId-key gets the cake - $viEntries = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId`, `status` FROM ?_videos WHERE (`status` & ?d) = 0 AND `id` IN (?a)', CC_FLAG_DELETED, $this->_get['id']); + $viEntries = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `userIdOwner`, `date`, `type`, `typeId`, `status` FROM ::videos WHERE (`status` & %i) = 0 AND `id` IN %in', CC_FLAG_DELETED, $this->_get['id']); foreach ($viEntries as $id => $viData) { // approve yet unapproved videos if (!($viData['status'] & CC_FLAG_APPROVED)) { // set as approved in DB - DB::Aowow()->query('UPDATE ?_videos SET `status` = ?d, `userIdApprove` = ?d WHERE `id` = ?d', CC_FLAG_APPROVED, User::$id, $id); + DB::Aowow()->qry('UPDATE ::videos SET `status` = %i, `userIdApprove` = %i WHERE `id` = %i', CC_FLAG_APPROVED, User::$id, $id); // gain siterep Util::gainSiteReputation($viData['userIdOwner'], SITEREP_ACTION_SUGGEST_VIDEO, ['id' => $id, 'what' => 1, 'date' => $viData['date']]); // flag DB entry as having videos if ($tbl = Type::getClassAttrib($viData['type'], 'dataTable')) - DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_VIDEO, $viData['typeId']); + DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_VIDEO, $viData['typeId']); } // reset all others - DB::Aowow()->query('UPDATE ?_videos a, ?_videos b SET a.`status` = a.`status` & ~?d WHERE a.`type` = b.`type` AND a.`typeId` = b.`typeId` AND a.`id` <> b.`id` AND b.`id` = ?d', CC_FLAG_STICKY, $id); + DB::Aowow()->qry('UPDATE ::videos a, ::videos b SET a.`status` = a.`status` & ~%i WHERE a.`type` = b.`type` AND a.`typeId` = b.`typeId` AND a.`id` <> b.`id` AND b.`id` = %i', CC_FLAG_STICKY, $id); // toggle sticky status - DB::Aowow()->query('UPDATE ?_videos SET `status` = IF(`status` & ?d, `status` & ~?d, `status` | ?d) WHERE `id` = ?d AND `status` & ?d', CC_FLAG_STICKY, CC_FLAG_STICKY, CC_FLAG_STICKY, $id, CC_FLAG_APPROVED); + DB::Aowow()->qry('UPDATE ::videos SET `status` = IF(`status` & %i, `status` & ~%i, `status` | %i) WHERE `id` = %i AND `status` & %i', CC_FLAG_STICKY, CC_FLAG_STICKY, CC_FLAG_STICKY, $id, CC_FLAG_APPROVED); unset($viEntries[$id]); } diff --git a/endpoints/admin/weight-presets.php b/endpoints/admin/weight-presets.php index a59e6ef6..3fa4a0ab 100644 --- a/endpoints/admin/weight-presets.php +++ b/endpoints/admin/weight-presets.php @@ -27,8 +27,8 @@ class AdminWeightpresetsResponse extends TemplateResponse $head = $body = ''; - $scales = DB::Aowow()->select('SELECT `class` AS ARRAY_KEY, `id` AS ARRAY_KEY2, `name`, `icon` FROM ?_account_weightscales WHERE `userId` = 0'); - $weights = DB::Aowow()->selectCol('SELECT awd.`id` AS ARRAY_KEY, awd.`field` AS ARRAY_KEY2, awd.`val` FROM ?_account_weightscale_data awd JOIN ?_account_weightscales ad ON awd.`id` = ad.`id` WHERE ad.`userId` = 0'); + $scales = DB::Aowow()->selectAssoc('SELECT `class` AS ARRAY_KEY, `id` AS ARRAY_KEY2, `name`, `icon` FROM ::account_weightscales WHERE `userId` = 0'); + $weights = DB::Aowow()->selectCol('SELECT awd.`id` AS ARRAY_KEY, awd.`field` AS ARRAY_KEY2, awd.`val` FROM ::account_weightscale_data awd JOIN ::account_weightscales ad ON awd.`id` = ad.`id` WHERE ad.`userId` = 0'); foreach ($scales as $cl => $data) { $ul = ''; diff --git a/endpoints/admin/weight-presets_save.php b/endpoints/admin/weight-presets_save.php index 8001cd4b..c73c17ff 100644 --- a/endpoints/admin/weight-presets_save.php +++ b/endpoints/admin/weight-presets_save.php @@ -30,8 +30,8 @@ class AdminWeightpresetsActionSaveResponse extends TextResponse } // save to db - DB::Aowow()->query('DELETE FROM ?_account_weightscale_data WHERE `id` = ?d', $this->_post['id']); - DB::Aowow()->query('UPDATE ?_account_weightscales SET `icon`= ? WHERE `id` = ?d', $this->_post['__icon'], $this->_post['id']); + DB::Aowow()->qry('DELETE FROM ::account_weightscale_data WHERE `id` = %i', $this->_post['id']); + DB::Aowow()->qry('UPDATE ::account_weightscales SET `icon`= %s WHERE `id` = %i', $this->_post['__icon'], $this->_post['id']); foreach (explode(',', $this->_post['scale']) as $s) { @@ -40,7 +40,7 @@ class AdminWeightpresetsActionSaveResponse extends TextResponse if (!Stat::getWeightJson($k) || $v < 1) continue; - if (DB::Aowow()->query('INSERT INTO ?_account_weightscale_data VALUES (?d, ?, ?d)', $this->_post['id'], $k, $v) === null) + if (DB::Aowow()->qry('INSERT INTO ::account_weightscale_data VALUES (%i, %s, %i)', $this->_post['id'], $k, $v) === null) { trigger_error('AdminWeightpresetsActionSaveResponse - failed to write to database', E_USER_ERROR); $this->result = self::ERR_WRITE_DB; diff --git a/endpoints/arena-team/arena-team.php b/endpoints/arena-team/arena-team.php index 04587f70..fc1e1a52 100644 --- a/endpoints/arena-team/arena-team.php +++ b/endpoints/arena-team/arena-team.php @@ -46,7 +46,7 @@ class ArenateamBaseResponse extends TemplateResponse // 3 possibilities // 1) already synced to aowow - if ($subject = DB::Aowow()->selectRow('SELECT `id`, `realmGUID`, `stub` 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` = %i AND `nameUrl` = %s', $this->realmId, Profiler::urlize($this->subjectName))) { $this->typeId = $subject['id']; @@ -57,16 +57,15 @@ class ArenateamBaseResponse extends TemplateResponse } // 2) not yet synced but exists on realm (wont work if we get passed an urlized name, but there is nothing we can do about it) - $subjects = DB::Characters($this->realmId)->select('SELECT at.`arenaTeamId` AS "realmGUID", at.`name`, at.`type` FROM arena_team at WHERE at.`name` = ?', $this->subjectName); - if ($subject = array_filter($subjects ?: [], fn($x) => Util::lower($x['name']) === Util::lower($this->subjectName))) + $subjects = DB::Characters($this->realmId)->selectAssoc('SELECT at.`arenaTeamId` AS "realmGUID", at.`name`, at.`type` FROM arena_team at WHERE at.`name` = %s', $this->subjectName); + if ($subject = array_find($subjects ?: [], fn($x) => Util::lower($x['name']) === Util::lower($this->subjectName))) { - $subject = array_pop($subject); $subject['realm'] = $this->realmId; $subject['stub'] = 1; $subject['nameUrl'] = Profiler::urlize($subject['name']); // create entry from realm with basic info - DB::Aowow()->query('INSERT IGNORE INTO ?_profiler_arena_team (?#) VALUES (?a)', array_keys($subject), array_values($subject)); + DB::Aowow()->qry('INSERT IGNORE INTO ::profiler_arena_team %v', $subject); $this->handleIncompleteData(Type::ARENA_TEAM, $subject['realmGUID']); return; diff --git a/endpoints/arena-team/resync.php b/endpoints/arena-team/resync.php index 8df05439..ac57929d 100644 --- a/endpoints/arena-team/resync.php +++ b/endpoints/arena-team/resync.php @@ -32,12 +32,12 @@ class ArenaTeamResyncResponse extends TextResponse if (!$this->assertGET('id')) return; - if ($teams = DB::Aowow()->select('SELECT `realm`, `realmGUID` FROM ?_profiler_arena_team WHERE `id` IN (?a)', $this->_get['id'])) + if ($teams = DB::Aowow()->selectAssoc('SELECT `realm`, `realmGUID` FROM ::profiler_arena_team WHERE `id` IN %in', $this->_get['id'])) foreach ($teams as $t) Profiler::scheduleResync(Type::ARENA_TEAM, $t['realm'], $t['realmGUID']); if ($this->_get['profile']) - if ($chars = DB::Aowow()->select('SELECT `realm`, `realmGUID` FROM ?_profiler_profiles p JOIN ?_profiler_arena_team_member atm ON atm.`profileId` = p.`id` WHERE atm.`arenaTeamId` IN (?a)', $this->_get['id'])) + if ($chars = DB::Aowow()->selectAssoc('SELECT `realm`, `realmGUID` FROM ::profiler_profiles p JOIN ::profiler_arena_team_member atm ON atm.`profileId` = p.`id` WHERE atm.`arenaTeamId` IN %in', $this->_get['id'])) foreach ($chars as $c) Profiler::scheduleResync(Type::PROFILE, $c['realm'], $c['realmGUID']); diff --git a/endpoints/class/class.php b/endpoints/class/class.php index 346cb5c0..47be4379 100644 --- a/endpoints/class/class.php +++ b/endpoints/class/class.php @@ -153,15 +153,15 @@ class ClassBaseResponse extends TemplateResponse implements ICache ['s.typeCat', [-13, -11, -2, 7]], [['s.cuFlags', (SPELL_CU_TRIGGERED | CUSTOM_EXCLUDE_FOR_LISTVIEW), '&'], 0], [ - 'OR', + DB::OR, // Glyphs, Proficiencies ['s.reqClassMask', $cl->toMask(), '&'], // Abilities / Talents ['s.skillLine1', $this->subject->getField('skills')], - ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->subject->getField('skills')]] + [DB::AND, ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->subject->getField('skills')]] ], [ // last rank or unranked - 'OR', + DB::OR, ['s.cuFlags', SPELL_CU_LAST_RANK, '&'], ['s.rankNo', 0] ] @@ -268,13 +268,13 @@ class ClassBaseResponse extends TemplateResponse implements ICache // tab: criteria-of $conditions = array( - 'AND', + DB::AND, ['ac.type', ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS], ['ac.value1', $this->typeId] ); - if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` IN (?a) AND `value1` = ?d', [ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE, ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE], $this->typeId)) - $conditions = ['OR', $conditions, ['ac.id', $extraCrt]]; + if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` IN %in AND `value1` = %i', [ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE, ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE], $this->typeId)) + $conditions = [DB::OR, $conditions, ['ac.id', $extraCrt]]; $crtOf = new AchievementList($conditions); if (!$crtOf->error) diff --git a/endpoints/comment/add-reply.php b/endpoints/comment/add-reply.php index ab2ab71d..6b9d7931 100644 --- a/endpoints/comment/add-reply.php +++ b/endpoints/comment/add-reply.php @@ -29,7 +29,7 @@ class CommentAddreplyResponse extends TextResponse if (!User::canReply()) $this->generate404(Lang::main('cannotComment')); - if (!$this->_post['commentId'] || !DB::Aowow()->selectCell('SELECT 1 FROM ?_comments WHERE `id` = ?d', $this->_post['commentId'])) + if (!$this->_post['commentId'] || !DB::Aowow()->selectCell('SELECT 1 FROM ::comments WHERE `id` = %i', $this->_post['commentId'])) { trigger_error('CommentAddreplyResponse - parent comment #'.$this->_post['commentId'].' does not exist', E_USER_ERROR); $this->generate404(Lang::main('intError')); @@ -38,7 +38,7 @@ class CommentAddreplyResponse extends TextResponse if (mb_strlen($this->_post['body']) < CommunityContent::REPLY_LENGTH_MIN || mb_strlen($this->_post['body']) > CommunityContent::REPLY_LENGTH_MAX) $this->generate404(Lang::main('textLength', [mb_strlen($this->_post['body']), CommunityContent::REPLY_LENGTH_MIN, CommunityContent::REPLY_LENGTH_MAX])); - if (!DB::Aowow()->query('INSERT INTO ?_comments (`userId`, `roles`, `body`, `date`, `replyTo`) VALUES (?d, ?d, ?, UNIX_TIMESTAMP(), ?d)', User::$id, User::$groups, $this->_post['body'], $this->_post['commentId'])) + if (!DB::Aowow()->qry('INSERT INTO ::comments (`userId`, `roles`, `body`, `date`, `replyTo`) VALUES (%i, %i, %s, UNIX_TIMESTAMP(), %i)', User::$id, User::$groups, $this->_post['body'], $this->_post['commentId'])) { trigger_error('CommentAddreplyResponse - write to db failed', E_USER_ERROR); $this->generate404(Lang::main('intError')); diff --git a/endpoints/comment/add.php b/endpoints/comment/add.php index 3cc8201e..78dffad6 100644 --- a/endpoints/comment/add.php +++ b/endpoints/comment/add.php @@ -30,7 +30,7 @@ class CommentAddResponse extends TextResponse // we now have a valid return target $idOrUrl = $this->_get['typeid']; if ($this->_get['type'] == Type::GUIDE) - if ($_ = DB::Aowow()->selectCell('SELECT `url` FROM ?_guides WHERE `id` = ?d', $this->_get['typeid'])) + if ($_ = DB::Aowow()->selectCell('SELECT `url` FROM ::guides WHERE `id` = %i', $this->_get['typeid'])) $idOrUrl = $_; $this->redirectTo = '?'.Type::getFileString($this->_get['type']).'='.$idOrUrl.'#comments'; @@ -57,16 +57,16 @@ class CommentAddResponse extends TextResponse return; } - if ($postId = DB::Aowow()->query('INSERT INTO ?_comments (`type`, `typeId`, `userId`, `roles`, `body`, `date`) VALUES (?d, ?d, ?d, ?d, ?, UNIX_TIMESTAMP())', $this->_get['type'], $this->_get['typeid'], User::$id, User::$groups, $this->_post['commentbody'])) + if ($postId = DB::Aowow()->qry('INSERT INTO ::comments (`type`, `typeId`, `userId`, `roles`, `body`, `date`) VALUES (%i, %i, %i, %i, %s, UNIX_TIMESTAMP())', $this->_get['type'], $this->_get['typeid'], User::$id, User::$groups, $this->_post['commentbody'])) { Util::gainSiteReputation(User::$id, SITEREP_ACTION_COMMENT, ['id' => $postId]); // every comment starts with a rating of +1 and i guess the simplest thing to do is create a db-entry with the system as owner - DB::Aowow()->query('INSERT INTO ?_user_ratings (`type`, `entry`, `userId`, `value`) VALUES (?d, ?d, 0, 1)', RATING_COMMENT, $postId); + DB::Aowow()->qry('INSERT INTO ::user_ratings (`type`, `entry`, `userId`, `value`) VALUES (%i, %i, 0, 1)', RATING_COMMENT, $postId); // flag target with hasComment if ($tbl = Type::getClassAttrib($this->_get['type'], 'dataTable')) - DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_COMMENT, $this->_get['typeid']); + DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_COMMENT, $this->_get['typeid']); return; } diff --git a/endpoints/comment/delete-reply.php b/endpoints/comment/delete-reply.php index 52b24b27..096a62dd 100644 --- a/endpoints/comment/delete-reply.php +++ b/endpoints/comment/delete-reply.php @@ -23,16 +23,13 @@ class CommentDeletereplyResponse extends TextResponse $this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'request malformed' : ''); } - // flag as deleted (unset sticky (can a reply even be sticky?) - $ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` & ~?d | ?d, `deleteUserId` = ?d, `deleteDate` = UNIX_TIMESTAMP() WHERE `id` = ?d { AND `userId` = ?d }', - CC_FLAG_STICKY, CC_FLAG_DELETED, - User::$id, - $this->_post['id'], - User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id - ); + $where = [['`id` = %i', $this->_post['id']]]; + if (!User::isInGroup(U_GROUP_MODERATOR)) + $where[] = ['`userId` = %i', User::$id]; - if ($ok) - DB::Aowow()->query('DELETE FROM ?_user_ratings WHERE `type` = ?d AND `entry` = ?d', RATING_COMMENT, $this->_post['id']); + // flag as deleted + if (DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` | %i, `deleteUserId` = %i, `deleteDate` = UNIX_TIMESTAMP() WHERE %and', CC_FLAG_DELETED, User::$id, $where)) + DB::Aowow()->qry('DELETE FROM ::user_ratings WHERE `type` = %i AND `entry` = %i', RATING_COMMENT, $this->_post['id']); else { trigger_error('CommentDeletereplyResponse - deleting reply #'.$this->_post['id'].' by user #'.User::$id.' from db failed', E_USER_ERROR); diff --git a/endpoints/comment/delete.php b/endpoints/comment/delete.php index 3893c308..582a0b01 100644 --- a/endpoints/comment/delete.php +++ b/endpoints/comment/delete.php @@ -24,24 +24,21 @@ class CommentDeleteResponse extends TextResponse } // in theory, there is a username passed alongside if executed from userpage... lets just use the current user (see user.js) - $ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` | ?d, `deleteUserId` = ?d, `deleteDate` = UNIX_TIMESTAMP() WHERE `id` IN (?a) { AND `userId` = ?d }', - CC_FLAG_DELETED, - User::$id, - $this->_post['id'], - User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id - ); + $where = [['`id` IN %in', $this->_post['id']]]; + if (!User::isInGroup(U_GROUP_MODERATOR)) + $where[] = ['`userId` = %i', User::$id]; - // unflag subject: hasComment - if ($ok) + // flag as deleted; unflag subject: hasComment + if (DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` | %i, `deleteUserId` = %i, `deleteDate` = UNIX_TIMESTAMP() WHERE %and', CC_FLAG_DELETED, User::$id, $where)) { - $coInfo = DB::Aowow()->select( - 'SELECT IF(BIT_OR(~b.`flags`) & ?d, 1, 0) AS "0", b.`type` AS "1", b.`typeId` AS "2" FROM ?_comments a JOIN ?_comments b ON a.`type` = b.`type` AND a.`typeId` = b.`typeId` WHERE a.`id` IN (?a) GROUP BY b.`type`, b.`typeId`', + $coInfo = DB::Aowow()->selectAssoc( + 'SELECT IF(BIT_OR(~b.`flags`) & %i, 1, 0) AS "0", b.`type` AS "1", b.`typeId` AS "2" FROM ::comments a JOIN ::comments b ON a.`type` = b.`type` AND a.`typeId` = b.`typeId` WHERE a.`id` IN %in GROUP BY b.`type`, b.`typeId`', CC_FLAG_DELETED, $this->_post['id'] ); foreach ($coInfo as [$hasMore, $type, $typeId]) if (!$hasMore && ($tbl = Type::getClassAttrib($type, 'dataTable'))) - DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` & ~?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_COMMENT, $typeId); + DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` & ~%i WHERE `id` = %i', $tbl, CUSTOM_HAS_COMMENT, $typeId); return; } diff --git a/endpoints/comment/detach-reply.php b/endpoints/comment/detach-reply.php index 6512a2fc..7c79f29a 100644 --- a/endpoints/comment/detach-reply.php +++ b/endpoints/comment/detach-reply.php @@ -23,7 +23,7 @@ class CommentDetachreplyResponse extends TextResponse $this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'request malformed' : ''); } - DB::Aowow()->query('UPDATE ?_comments c1, ?_comments c2 SET c1.`replyTo` = 0, c1.`type` = c2.`type`, c1.`typeId` = c2.`typeId` WHERE c1.`replyTo` = c2.`id` AND c1.`id` = ?d', $this->_post['id']); + DB::Aowow()->qry('UPDATE ::comments c1, ::comments c2 SET c1.`replyTo` = 0, c1.`type` = c2.`type`, c1.`typeId` = c2.`typeId` WHERE c1.`replyTo` = c2.`id` AND c1.`id` = %i', $this->_post['id']); } } diff --git a/endpoints/comment/downvote-reply.php b/endpoints/comment/downvote-reply.php index 9637bdc3..cd035abc 100644 --- a/endpoints/comment/downvote-reply.php +++ b/endpoints/comment/downvote-reply.php @@ -26,7 +26,7 @@ class CommentDownvotereplyResponse extends TextResponse if (!User::canDownvote()) $this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'cannot downvote' : ''); - $comment = DB::Aowow()->selectRow('SELECT `userId`, IF(`flags` & ?d, 1, 0) AS "deleted" FROM ?_comments WHERE `id` = ?d', CC_FLAG_DELETED, $this->_post['id']); + $comment = DB::Aowow()->selectRow('SELECT `userId`, IF(`flags` & %i, 1, 0) AS "deleted" FROM ::comments WHERE `id` = %i', CC_FLAG_DELETED, $this->_post['id']); if (!$comment) { trigger_error('CommentDownvotereplyResponse - comment #'.$this->_post['id'].' not found in db', E_USER_ERROR); @@ -39,15 +39,9 @@ class CommentDownvotereplyResponse extends TextResponse if ($comment['deleted']) $this->generate404('LANG.votedeleted_tip'); - $ok = DB::Aowow()->query( - 'INSERT INTO ?_user_ratings (`type`, `entry`, `userId`, `value`) VALUES (?d, ?d, ?d, ?d)', - RATING_COMMENT, - $this->_post['id'], - User::$id, - User::canSupervote() ? -2 : -1 - ); - - if (!is_int($ok)) + if (is_null(DB::Aowow()->qry('INSERT INTO ::user_ratings (`type`, `entry`, `userId`, `value`) VALUES (%i, %i, %i, %i)', + RATING_COMMENT, $this->_post['id'], User::$id, User::canSupervote() ? -2 : -1 + ))) { trigger_error('CommentDownvotereplyResponse - write to db failed', E_USER_ERROR); $this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'write to db failed' : ''); diff --git a/endpoints/comment/edit-reply.php b/endpoints/comment/edit-reply.php index fa56e999..7a6aed50 100644 --- a/endpoints/comment/edit-reply.php +++ b/endpoints/comment/edit-reply.php @@ -26,7 +26,7 @@ class CommentEditreplyResponse extends TextResponse $this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'request malformed' : ''); } - $ownerId = DB::Aowow()->selectCell('SELECT `userId` FROM ?_comments WHERE `id` = ?d AND `replyTo` = ?d', $this->_post['replyId'], $this->_post['commentId']); + $ownerId = DB::Aowow()->selectCell('SELECT `userId` FROM ::comments WHERE `id` = %i AND `replyTo` = %i', $this->_post['replyId'], $this->_post['commentId']); if (!User::canReply() || (User::$id != $ownerId && !User::isInGroup(U_GROUP_MODERATOR))) $this->generate404(Lang::main('cannotComment')); @@ -48,8 +48,11 @@ class CommentEditreplyResponse extends TextResponse if (User::$id == $ownerId) $update['roles'] = User::$groups; - if (!DB::Aowow()->query('UPDATE ?_comments SET `editCount` = `editCount` + 1, ?a WHERE `id` = ?d AND `replyTo` = ?d { AND `userId` = ?d }', - $update, $this->_post['replyId'], $this->_post['commentId'], User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id)) + $where = [['`id` = %i', $this->_post['replyId']], ['`replyTo` = %i', $this->_post['commentId']]]; + if (!User::isInGroup(U_GROUP_MODERATOR)) + $where[] = ['`userId` = %i', User::$id]; + + if (!DB::Aowow()->qry('UPDATE ::comments SET `editCount` = `editCount` + 1, %a WHERE %and', $update, $where)) { trigger_error('CommentEditreplyResponse - write to db failed', E_USER_ERROR); $this->generate404(Lang::main('intError')); diff --git a/endpoints/comment/edit.php b/endpoints/comment/edit.php index 4969990d..a3a2e3cb 100644 --- a/endpoints/comment/edit.php +++ b/endpoints/comment/edit.php @@ -26,7 +26,7 @@ class CommentEditResponse extends TextResponse return; } - $ownerId = DB::Aowow()->selectCell('SELECT `userId` FROM ?_comments WHERE `id` = ?d', $this->_get['id']); + $ownerId = DB::Aowow()->selectCell('SELECT `userId` FROM ::comments WHERE `id` = %i', $this->_get['id']); if (!User::canComment() || (User::$id != $ownerId && !User::isInGroup(U_GROUP_MODERATOR))) { @@ -56,7 +56,7 @@ class CommentEditResponse extends TextResponse $update['responseRoles'] = User::$groups; } - DB::Aowow()->query('UPDATE ?_comments SET `editCount` = `editCount` + 1, ?a WHERE `id` = ?d', $update, $this->_get['id']); + DB::Aowow()->qry('UPDATE ::comments SET `editCount` = `editCount` + 1, %a WHERE `id` = %i', $update, $this->_get['id']); } } diff --git a/endpoints/comment/flag-reply.php b/endpoints/comment/flag-reply.php index 91044e50..55589b45 100644 --- a/endpoints/comment/flag-reply.php +++ b/endpoints/comment/flag-reply.php @@ -23,7 +23,7 @@ class CommentFlagreplyResponse extends TextResponse $this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'request malformed' : ''); } - $replyOwner = DB::Aowow()->selectCell('SELECT `userId` FROM ?_commments WHERE `id` = ?d', $this->_post['id']); + $replyOwner = DB::Aowow()->selectCell('SELECT `userId` FROM ::commments WHERE `id` = %i', $this->_post['id']); if (!$replyOwner) { trigger_error('CommentFlagreplyResponse - reply not found', E_USER_ERROR); @@ -38,7 +38,7 @@ class CommentFlagreplyResponse extends TextResponse if (!$report->create('Report Reply Button Click')) $this->generate404('LANG.ct_resp_error'.$report->getError()); else if (count($report->getSimilar()) >= CommunityContent::REPORT_THRESHOLD_AUTO_DELETE) - DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` | ?d WHERE `id` = ?d', CC_FLAG_DELETED, $this->_post['id']); + DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` | %i WHERE `id` = %i', CC_FLAG_DELETED, $this->_post['id']); } } diff --git a/endpoints/comment/out-of-date.php b/endpoints/comment/out-of-date.php index d1c35432..70cb3dfd 100644 --- a/endpoints/comment/out-of-date.php +++ b/endpoints/comment/out-of-date.php @@ -30,9 +30,9 @@ class CommentOutofdateResponse extends TextResponse if (User::isInGroup(U_GROUP_MODERATOR)) // directly mark as outdated { if (!$this->_post['remove']) - $ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` | ?d WHERE `id` = ?d', CC_FLAG_OUTDATED, $this->_post['id']); + $ok = DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` | %i WHERE `id` = %i', CC_FLAG_OUTDATED, $this->_post['id']); else - $ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` & ~?d WHERE `id` = ?d', CC_FLAG_OUTDATED, $this->_post['id']); + $ok = DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` & ~%i WHERE `id` = %i', CC_FLAG_OUTDATED, $this->_post['id']); } else // try to report as outdated { @@ -41,7 +41,7 @@ class CommentOutofdateResponse extends TextResponse $this->result = Lang::main('intError'); if (count($report->getSimilar()) >= CommunityContent::REPORT_THRESHOLD_AUTO_OUT_OF_DATE) - $ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` | ?d WHERE `id` = ?d', CC_FLAG_OUTDATED, $this->_post['id']); + $ok = DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` | %i WHERE `id` = %i', CC_FLAG_OUTDATED, $this->_post['id']); } if (!$ok) diff --git a/endpoints/comment/rating.php b/endpoints/comment/rating.php index bf69da13..d080e71e 100644 --- a/endpoints/comment/rating.php +++ b/endpoints/comment/rating.php @@ -21,7 +21,7 @@ class CommentRatingResponse extends TextResponse return; } - if ($votes = DB::Aowow()->selectRow('SELECT 1 AS "success", SUM(IF(`value` > 0, `value`, 0)) AS "up", SUM(IF(`value` < 0, -`value`, 0)) AS "down" FROM ?_user_ratings WHERE `type` = ?d AND `entry` = ?d AND `userId` <> 0 GROUP BY `entry`', RATING_COMMENT, $this->_get['id'])) + if ($votes = DB::Aowow()->selectRow('SELECT 1 AS "success", SUM(IF(`value` > 0, `value`, 0)) AS "up", SUM(IF(`value` < 0, -`value`, 0)) AS "down" FROM ::user_ratings WHERE `type` = %i AND `entry` = %i AND `userId` <> 0 GROUP BY `entry`', RATING_COMMENT, $this->_get['id'])) $this->result = Util::toJSON($votes); else $this->result = Util::toJSON(['success' => 1, 'up' => 0, 'down' => 0]); diff --git a/endpoints/comment/sticky.php b/endpoints/comment/sticky.php index f2ecd1e9..16fcf3a7 100644 --- a/endpoints/comment/sticky.php +++ b/endpoints/comment/sticky.php @@ -25,9 +25,9 @@ class CommentStickyResponse extends TextResponse } if ($this->_post['sticky']) - DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` | ?d WHERE `id` = ?d', CC_FLAG_STICKY, $this->_post['id']); + DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` | %i WHERE `id` = %i', CC_FLAG_STICKY, $this->_post['id']); else - DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` & ~?d WHERE `id` = ?d', CC_FLAG_STICKY, $this->_post['id']); + DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` & ~%i WHERE `id` = %i', CC_FLAG_STICKY, $this->_post['id']); } } diff --git a/endpoints/comment/undelete.php b/endpoints/comment/undelete.php index eb56df49..1d21a6a1 100644 --- a/endpoints/comment/undelete.php +++ b/endpoints/comment/undelete.php @@ -24,19 +24,20 @@ class CommentUndeleteResponse extends TextResponse } // in theory, there is a username passed alongside if executed from userpage... lets just use the current user (see user.js) - $ok = DB::Aowow()->query('UPDATE ?_comments SET `flags` = `flags` & ~?d WHERE `id` IN (?a) { AND `userId` = `deleteUserId` AND `deleteUserId` = ?d }', - CC_FLAG_DELETED, - $this->_post['id'], - User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id - ); + $where = [['`id` IN %in', $this->_post['id']]]; + if (!User::isInGroup(U_GROUP_MODERATOR)) + { + $where[] = ['`deleteUserId` = `userId']; + $where[] = ['`deleteUserId` = %i', User::$id]; + } // unflag subject: hasComment - if ($ok) + if (DB::Aowow()->qry('UPDATE ::comments SET `flags` = `flags` & ~%i WHERE %and', CC_FLAG_DELETED, $where)) { - $coInfo = DB::Aowow()->select('SELECT `type` AS "0", `typeId` AS "1" FROM ?_comments WHERE `id` IN (?a) GROUP BY `type`, `typeId`', $this->_post['id']); + $coInfo = DB::Aowow()->selectAssoc('SELECT `type` AS "0", `typeId` AS "1" FROM ::comments WHERE `id` IN %in GROUP BY `type`, `typeId`', $this->_post['id']); foreach ($coInfo as [$type, $typeId]) if ($tbl = Type::getClassAttrib($type, 'dataTable')) - DB::Aowow()->query('UPDATE ?# SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', $tbl, CUSTOM_HAS_COMMENT, $typeId); + DB::Aowow()->qry('UPDATE %n SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', $tbl, CUSTOM_HAS_COMMENT, $typeId); return; } diff --git a/endpoints/comment/upvote-reply.php b/endpoints/comment/upvote-reply.php index 91fedf47..f6e84a34 100644 --- a/endpoints/comment/upvote-reply.php +++ b/endpoints/comment/upvote-reply.php @@ -26,7 +26,7 @@ class CommentUpvotereplyResponse extends TextResponse if (!User::canUpvote()) $this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'cannot upvote' : ''); - $comment = DB::Aowow()->selectRow('SELECT `userId`, IF(`flags` & ?d, 1, 0) AS "deleted" FROM ?_comments WHERE `id` = ?d', CC_FLAG_DELETED, $this->_post['id']); + $comment = DB::Aowow()->selectRow('SELECT `userId`, IF(`flags` & %i, 1, 0) AS "deleted" FROM ::comments WHERE `id` = %i', CC_FLAG_DELETED, $this->_post['id']); if (!$comment) { trigger_error('CommentUpvotereplyResponse - comment #'.$this->_post['id'].' not found in db', E_USER_ERROR); @@ -39,15 +39,9 @@ class CommentUpvotereplyResponse extends TextResponse if ($comment['deleted']) $this->generate404('LANG.votedeleted_tip'); - $ok = DB::Aowow()->query( - 'INSERT INTO ?_user_ratings (`type`, `entry`, `userId`, `value`) VALUES (?d, ?d, ?d, ?d)', - RATING_COMMENT, - $this->_post['id'], - User::$id, - User::canSupervote() ? 2 : 1 - ); - - if (!is_int($ok)) + if (is_null(DB::Aowow()->qry('INSERT INTO ::user_ratings (`type`, `entry`, `userId`, `value`) VALUES (%i, %i, %i, %i)', + RATING_COMMENT, $this->_post['id'], User::$id, User::canSupervote() ? 2 : 1 + ))) { trigger_error('CommentUpvotereplyResponse - write to db failed', E_USER_ERROR); $this->generate404(User::isInGroup(U_GROUP_STAFF) ? 'write to db failed' : ''); diff --git a/endpoints/comment/vote.php b/endpoints/comment/vote.php index 7f459253..1bf3b1ff 100644 --- a/endpoints/comment/vote.php +++ b/endpoints/comment/vote.php @@ -32,7 +32,7 @@ class CommentVoteResponse extends TextResponse } $target = DB::Aowow()->selectRow( - 'SELECT c.`userId` AS "owner", ur.`value`, IF(c.`flags` & ?d, 1, 0) AS "deleted" FROM ?_comments c LEFT JOIN ?_user_ratings ur ON ur.`type` = ?d AND ur.`entry` = c.id AND ur.`userId` = ?d WHERE c.id = ?d', + 'SELECT c.`userId` AS "owner", ur.`value`, IF(c.`flags` & %i, 1, 0) AS "deleted" FROM ::comments c LEFT JOIN ::user_ratings ur ON ur.`type` = %i AND ur.`entry` = c.id AND ur.`userId` = %i WHERE c.id = %i', CC_FLAG_DELETED, RATING_COMMENT, User::$id, $this->_get['id'] ); if (!$target) @@ -62,9 +62,9 @@ class CommentVoteResponse extends TextResponse $ok = false; // old and new have same sign; undo vote (user may have gained/lost access to superVote in the meantime) if ($target['value'] && ($target['value'] < 0) == ($val < 0)) - $ok = DB::Aowow()->query('DELETE FROM ?_user_ratings WHERE `type` = ?d AND `entry` = ?d AND `userId` = ?d', RATING_COMMENT, $this->_get['id'], User::$id); + $ok = DB::Aowow()->qry('DELETE FROM ::user_ratings WHERE `type` = %i AND `entry` = %i AND `userId` = %i', RATING_COMMENT, $this->_get['id'], User::$id); else // replace, because we may be overwriting an old, opposing vote - if ($ok = DB::Aowow()->query('REPLACE INTO ?_user_ratings (`type`, `entry`, `userId`, `value`) VALUES (?d, ?d, ?d, ?d)', RATING_COMMENT, $this->_get['id'], User::$id, $val)) + if ($ok = DB::Aowow()->qry('REPLACE INTO ::user_ratings (`type`, `entry`, `userId`, `value`) VALUES (%i, %i, %i, %i)', RATING_COMMENT, $this->_get['id'], User::$id, $val)) User::decrementDailyVotes(); // do not refund retracted votes! if ($ok) diff --git a/endpoints/cookie/cookie.php b/endpoints/cookie/cookie.php index e62793e8..5b5f9af0 100644 --- a/endpoints/cookie/cookie.php +++ b/endpoints/cookie/cookie.php @@ -32,7 +32,7 @@ class CookieBaseResponse extends TextResponse { if (!$this->param && $this->_get['purge']) { - if (User::$id && DB::Aowow()->query('UPDATE ?_account_cookies SET `data` = "purged" WHERE `userId` = ?d AND `name` LIKE "announcement-%"', User::$id) !== null) + if (User::$id && DB::Aowow()->qry('UPDATE ::account_cookies SET `data` = "purged" WHERE `userId` = %i AND `name` LIKE "announcement-%"', User::$id) !== null) $this->result = 0; return; @@ -44,7 +44,7 @@ class CookieBaseResponse extends TextResponse return; } - if (DB::Aowow()->query('REPLACE INTO ?_account_cookies VALUES (?d, ?, ?)', User::$id, $this->param, $this->_get[$this->param])) + if (DB::Aowow()->qry('REPLACE INTO ::account_cookies VALUES (%i, %s, %s)', User::$id, $this->param, $this->_get[$this->param])) $this->result = 0; else trigger_error('CookieBaseResponse - write to db failed', E_USER_ERROR); diff --git a/endpoints/currency/currency.php b/endpoints/currency/currency.php index 8bf76fd1..92a761a7 100644 --- a/endpoints/currency/currency.php +++ b/endpoints/currency/currency.php @@ -201,7 +201,7 @@ class CurrencyBaseResponse extends TemplateResponse implements ICache // tab: created by (spell) [for items its handled in LootByItem] if ($this->typeId == CURRENCY_HONOR_POINTS) { - $createdBy = new SpellList(array(['effect1Id', SPELL_EFFECT_ADD_HONOR], ['effect2Id', SPELL_EFFECT_ADD_HONOR], ['effect3Id', SPELL_EFFECT_ADD_HONOR], 'OR')); + $createdBy = new SpellList(array(['effect1Id', SPELL_EFFECT_ADD_HONOR], ['effect2Id', SPELL_EFFECT_ADD_HONOR], ['effect3Id', SPELL_EFFECT_ADD_HONOR], DB::OR)); if (!$createdBy->error) { $this->extendGlobalData($createdBy->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); @@ -237,8 +237,8 @@ class CurrencyBaseResponse extends TemplateResponse implements ICache if (!$n && !is_null(ItemListFilter::getCriteriaIndex(158, $_relItemId))) $n = '?items&filter=cr=158;crs='.$_relItemId.';crv=0'; - $xCosts = DB::Aowow()->selectCol('SELECT `id` FROM ?_itemextendedcost WHERE '.$w); - $boughtBy = $xCosts ? DB::World()->selectCol('SELECT `item` FROM npc_vendor WHERE `extendedCost` IN (?a) UNION SELECT `item` FROM game_event_npc_vendor WHERE `extendedCost` IN (?a)', $xCosts, $xCosts) : []; + $xCosts = DB::Aowow()->selectCol('SELECT `id` FROM ::itemextendedcost WHERE '.$w); + $boughtBy = $xCosts ? DB::World()->selectCol('SELECT `item` FROM npc_vendor WHERE `extendedCost` IN %in UNION SELECT `item` FROM game_event_npc_vendor WHERE `extendedCost` IN %in', $xCosts, $xCosts) : []; if ($boughtBy) { $boughtBy = new ItemList(array(['id', $boughtBy])); diff --git a/endpoints/emote/emote.php b/endpoints/emote/emote.php index b5b64f9e..8a73cfdd 100644 --- a/endpoints/emote/emote.php +++ b/endpoints/emote/emote.php @@ -109,7 +109,7 @@ class EmoteBaseResponse extends TemplateResponse implements ICache if ($this->subject->getField('cuFlags') & EMOTE_CU_MISSING_CMD) $text .= Lang::emote('noCommand').'[br][br]'; - else if ($aliasses = DB::Aowow()->selectCol('SELECT `command` FROM ?_emotes_aliasses WHERE `id` = ?d AND `locales` & ?d', $this->typeId, 1 << Lang::getLocale()->value)) + else if ($aliasses = DB::Aowow()->selectCol('SELECT `command` FROM ::emotes_aliasses WHERE `id` = %i AND `locales` & %i', $this->typeId, 1 << Lang::getLocale()->value)) { $text .= '[h3]'.Lang::emote('aliases').'[/h3][ul]'; foreach ($aliasses as $a) @@ -184,13 +184,12 @@ class EmoteBaseResponse extends TemplateResponse implements ICache } // tab: sound - $ems = DB::Aowow()->select( + $ems = DB::Aowow()->selectAssoc( 'SELECT `soundId` AS ARRAY_KEY, BIT_OR(1 << (`raceId` - 1)) AS "raceMask", BIT_OR(1 << (`gender` - 1)) AS "gender" - FROM ?_emotes_sounds - WHERE `emoteId` = ?d { OR -`emoteId` = ?d } + FROM ::emotes_sounds + WHERE %if', $this->typeId < 0, '-`emoteId` = %i OR', $this->subject->getField('parentEmote'), '%end `emoteId` = %i GROUP BY `soundId`', $this->typeId, - $this->typeId < 0 ? $this->subject->getField('parentEmote') : DBSIMPLE_SKIP ); if ($ems) diff --git a/endpoints/enchantment/enchantment.php b/endpoints/enchantment/enchantment.php index 7efcee08..98ae613f 100644 --- a/endpoints/enchantment/enchantment.php +++ b/endpoints/enchantment/enchantment.php @@ -194,10 +194,10 @@ class EnchantmentBaseResponse extends TemplateResponse implements ICache // used by spell // used by useItem $cnd = array( - 'OR', - ['AND', ['effect1Id', SpellList::EFFECTS_ENCHANTMENT], ['effect1MiscValue', $this->typeId]], - ['AND', ['effect2Id', SpellList::EFFECTS_ENCHANTMENT], ['effect2MiscValue', $this->typeId]], - ['AND', ['effect3Id', SpellList::EFFECTS_ENCHANTMENT], ['effect3MiscValue', $this->typeId]], + DB::OR, + [DB::AND, ['effect1Id', SpellList::EFFECTS_ENCHANTMENT], ['effect1MiscValue', $this->typeId]], + [DB::AND, ['effect2Id', SpellList::EFFECTS_ENCHANTMENT], ['effect2MiscValue', $this->typeId]], + [DB::AND, ['effect3Id', SpellList::EFFECTS_ENCHANTMENT], ['effect3MiscValue', $this->typeId]], ); $spellList = new SpellList($cnd); if (!$spellList->error) @@ -207,12 +207,12 @@ class EnchantmentBaseResponse extends TemplateResponse implements ICache $spellIds = $spellList->getFoundIDs(); $conditions = array( - 'OR', - ['AND', ['spellTrigger1', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId1', $spellIds]], - ['AND', ['spellTrigger2', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId2', $spellIds]], - ['AND', ['spellTrigger3', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId3', $spellIds]], - ['AND', ['spellTrigger4', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId4', $spellIds]], - ['AND', ['spellTrigger5', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId5', $spellIds]] + DB::OR, + [DB::AND, ['spellTrigger1', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId1', $spellIds]], + [DB::AND, ['spellTrigger2', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId2', $spellIds]], + [DB::AND, ['spellTrigger3', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId3', $spellIds]], + [DB::AND, ['spellTrigger4', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId4', $spellIds]], + [DB::AND, ['spellTrigger5', [SPELL_TRIGGER_USE, SPELL_TRIGGER_USE_NODELAY]], ['spellId5', $spellIds]] ); $ubItems = new ItemList($conditions); @@ -259,13 +259,13 @@ class EnchantmentBaseResponse extends TemplateResponse implements ICache } // used by randomAttrItem - $ire = DB::Aowow()->select( - 'SELECT *, ABS(`id`) AS ARRAY_KEY FROM ?_itemrandomenchant WHERE `enchantId1` = ?d OR `enchantId2` = ?d OR `enchantId3` = ?d OR `enchantId4` = ?d OR `enchantId5` = ?d', + $ire = DB::Aowow()->selectAssoc( + 'SELECT *, ABS(`id`) AS ARRAY_KEY FROM ::itemrandomenchant WHERE `enchantId1` = %i OR `enchantId2` = %i OR `enchantId3` = %i OR `enchantId4` = %i OR `enchantId5` = %i', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId ); if ($ire) { - if ($iet = DB::World()->select('SELECT `entry` AS ARRAY_KEY, `ench`, `chance` FROM item_enchantment_template WHERE `ench` IN (?a)', array_keys($ire))) + if ($iet = DB::World()->selectAssoc('SELECT `entry` AS ARRAY_KEY, `ench`, `chance` FROM item_enchantment_template WHERE `ench` IN %in', array_keys($ire))) { $randIds = []; // transform back to signed format foreach ($iet as $tplId => $data) diff --git a/endpoints/event/event.php b/endpoints/event/event.php index 143b5f71..7796afc1 100644 --- a/endpoints/event/event.php +++ b/endpoints/event/event.php @@ -114,7 +114,7 @@ class EventBaseResponse extends TemplateResponse implements ICache /* Main Content */ /****************/ - // no entry in ?_articles? use default HolidayDescription + // no entry in ::articles? use default HolidayDescription if ($_holidayId && empty($this->article)) $this->article = new Markup($this->subject->getField('description', true), ['dbpage' => true]); @@ -137,7 +137,7 @@ class EventBaseResponse extends TemplateResponse implements ICache $this->lvTabs = new Tabs(['parent' => "\$\$WH.ge('tabs-generic')"], 'tabsRelated', true); // tab: npcs - if ($npcIds = DB::World()->selectCol('SELECT `id` AS ARRAY_KEY, IF(ec.`eventEntry` > 0, 1, 0) AS "added" FROM creature c, game_event_creature ec WHERE ec.`guid` = c.`guid` AND ABS(ec.`eventEntry`) = ?d', $this->typeId)) + if ($npcIds = DB::World()->selectCol('SELECT `id` AS ARRAY_KEY, IF(ec.`eventEntry` > 0, 1, 0) AS "added" FROM creature c, game_event_creature ec WHERE ec.`guid` = c.`guid` AND ABS(ec.`eventEntry`) = %i', $this->typeId)) { $creatures = new CreatureList(array(['id', array_keys($npcIds)])); if (!$creatures->error) @@ -157,7 +157,7 @@ class EventBaseResponse extends TemplateResponse implements ICache } // tab: objects - if ($objectIds = DB::World()->selectCol('SELECT `id` AS ARRAY_KEY, IF(eg.`eventEntry` > 0, 1, 0) AS "added" FROM gameobject g, game_event_gameobject eg WHERE eg.`guid` = g.`guid` AND ABS(eg.`eventEntry`) = ?d', $this->typeId)) + if ($objectIds = DB::World()->selectCol('SELECT `id` AS ARRAY_KEY, IF(eg.`eventEntry` > 0, 1, 0) AS "added" FROM gameobject g, game_event_gameobject eg WHERE eg.`guid` = g.`guid` AND ABS(eg.`eventEntry`) = %i', $this->typeId)) { $objects = new GameObjectList(array(['id', array_keys($objectIds)])); if (!$objects->error) @@ -205,7 +205,7 @@ class EventBaseResponse extends TemplateResponse implements ICache if ($_holidayId) { // tab: criteria-of - if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` = ?d AND `value1` = ?d', ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY, $_holidayId)) + if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` = %i AND `value1` = %i', ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY, $_holidayId)) { $condition = array(['ac.id', $extraCrt]); if ($exclAcvs) @@ -260,9 +260,9 @@ class EventBaseResponse extends TemplateResponse implements ICache // vendor $cIds = $creatures->getFoundIDs(); if ($sells = DB::World()->selectCol( - 'SELECT `item` FROM npc_vendor nv WHERE `entry` IN (?a) UNION - SELECT nv1.`item` FROM npc_vendor nv1 JOIN npc_vendor nv2 ON -nv1.`entry` = nv2.`item` WHERE nv2.`entry` IN (?a) UNION - SELECT `item` FROM game_event_npc_vendor genv JOIN creature c ON genv.`guid` = c.`guid` WHERE c.`id` IN (?a)', + 'SELECT `item` FROM npc_vendor nv WHERE `entry` IN %in UNION + SELECT nv1.`item` FROM npc_vendor nv1 JOIN npc_vendor nv2 ON -nv1.`entry` = nv2.`item` WHERE nv2.`entry` IN %in UNION + SELECT `item` FROM game_event_npc_vendor genv JOIN creature c ON genv.`guid` = c.`guid` WHERE c.`id` IN %in', $cIds, $cIds, $cIds )) $itemCnd[] = ['id', $sells]; @@ -272,7 +272,7 @@ class EventBaseResponse extends TemplateResponse implements ICache // not checking for loot ... cant distinguish between eventLoot and fillerCrapLoot if ($itemCnd) { - array_unshift($itemCnd, 'OR'); + array_unshift($itemCnd, DB::OR); $eventItems = new ItemList($itemCnd); if (!$eventItems->error) { @@ -288,7 +288,7 @@ class EventBaseResponse extends TemplateResponse implements ICache } // tab: see also (event conditions) - if ($rel = DB::World()->selectCol('SELECT IF(`eventEntry` = `prerequisite_event`, NULL, IF(`eventEntry` = ?d, `prerequisite_event`, -`eventEntry`)) FROM game_event_prerequisite WHERE `prerequisite_event` = ?d OR `eventEntry` = ?d', $this->typeId, $this->typeId, $this->typeId)) + if ($rel = DB::World()->selectCol('SELECT IF(`eventEntry` = `prerequisite_event`, NULL, IF(`eventEntry` = %i, `prerequisite_event`, -`eventEntry`)) FROM game_event_prerequisite WHERE `prerequisite_event` = %i OR `eventEntry` = %i', $this->typeId, $this->typeId, $this->typeId)) { if (array_filter($rel, fn($x) => $x === null)) trigger_error('game_event_prerequisite: this event has itself as prerequisite', E_USER_WARNING); diff --git a/endpoints/faction/faction.php b/endpoints/faction/faction.php index 96b887d8..e85f5a79 100644 --- a/endpoints/faction/faction.php +++ b/endpoints/faction/faction.php @@ -102,8 +102,8 @@ class FactionBaseResponse extends TemplateResponse implements ICache // profiler relateed (note that this is part of the cache. I don't think this is important enough to calc for every view) 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 `exalted` = 1 AND `factionId` = ?d', $this->typeId); - $y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_profiles WHERE `custom` = 0 AND `stub` = 0'); + $x = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ::profiler_completion_reputation WHERE `exalted` = 1 AND `factionId` = %i', $this->typeId); + $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 @@ -132,7 +132,7 @@ class FactionBaseResponse extends TemplateResponse implements ICache CONCAT_WS(" ", faction1, faction2, faction3, faction4) AS faction, CONCAT_WS(" ", rate_1, rate_2, rate_3, rate_4) AS rate, CONCAT_WS(" ", rank_1, rank_2, rank_3, rank_4) AS rank - FROM reputation_spillover_template WHERE faction = ?d', $this->typeId); + FROM reputation_spillover_template WHERE faction = %i', $this->typeId); */ @@ -142,7 +142,7 @@ class FactionBaseResponse extends TemplateResponse implements ICache ); if ($p = $this->subject->getField('parentFactionId')) // linked via parent - $conditions[] = ['OR', ['id', $p], ['parentFactionId', $p]]; + $conditions[] = [DB::OR, ['id', $p], ['parentFactionId', $p]]; else // self as parent $conditions[] = ['parentFactionId', $this->typeId]; @@ -162,7 +162,7 @@ class FactionBaseResponse extends TemplateResponse implements ICache ); // reward rates (ultimately this should be calculated into each reward display) - if ($rates = DB::World()->selectRow('SELECT `quest_rate`, `quest_daily_rate`, `quest_weekly_rate`, `quest_monthly_rate`, `quest_repeatable_rate`, `creature_rate`, `spell_rate` FROM reputation_reward_rate WHERE `faction` = ?d', $this->typeId)) + if ($rates = DB::World()->selectRow('SELECT `quest_rate`, `quest_daily_rate`, `quest_weekly_rate`, `quest_monthly_rate`, `quest_repeatable_rate`, `creature_rate`, `spell_rate` FROM reputation_reward_rate WHERE `faction` = %i', $this->typeId)) { $buff = ''; foreach ($rates as $k => $v) @@ -191,7 +191,7 @@ class FactionBaseResponse extends TemplateResponse implements ICache } // factionchange-equivalent - if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = ?d, `alliance_id`, -`horde_id`) FROM player_factionchange_reputations WHERE `alliance_id` = ?d OR `horde_id` = ?d', $this->typeId, $this->typeId, $this->typeId)) + if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = %i, `alliance_id`, -`horde_id`) FROM player_factionchange_reputations WHERE `alliance_id` = %i OR `horde_id` = %i', $this->typeId, $this->typeId, $this->typeId)) { $altFac = new FactionList(array(['id', abs($pendant)])); if (!$altFac->error) @@ -237,11 +237,11 @@ class FactionBaseResponse extends TemplateResponse implements ICache { // inherit siblings/children from $spillover $cRep = DB::World()->selectCol('SELECT DISTINCT `creature_id` AS ARRAY_KEY, `qty` FROM ( - SELECT `creature_id`, `RewOnKillRepValue1` as "qty" FROM creature_onkill_reputation WHERE `RewOnKillRepValue1` > 0 AND (`RewOnKillRepFaction1` = ?d { OR (`RewOnKillRepFaction1` IN (?a) AND `IsTeamAward1` <> 0) } ) UNION - SELECT `creature_id`, `RewOnKillRepValue2` as "qty" FROM creature_onkill_reputation WHERE `RewOnKillRepValue2` > 0 AND (`RewOnKillRepFaction2` = ?d { OR (`RewOnKillRepFaction2` IN (?a) AND `IsTeamAward2` <> 0) } ) + SELECT `creature_id`, `RewOnKillRepValue1` as "qty" FROM creature_onkill_reputation WHERE `RewOnKillRepValue1` > 0 AND (`RewOnKillRepFaction1` = %i OR (`RewOnKillRepFaction1` IN %in AND `IsTeamAward1` <> 0) ) UNION + SELECT `creature_id`, `RewOnKillRepValue2` as "qty" FROM creature_onkill_reputation WHERE `RewOnKillRepValue2` > 0 AND (`RewOnKillRepFaction2` = %i OR (`RewOnKillRepFaction2` IN %in AND `IsTeamAward2` <> 0) ) ) x', - $this->typeId, $spillover->getFoundIDs() ?: DBSIMPLE_SKIP, - $this->typeId, $spillover->getFoundIDs() ?: DBSIMPLE_SKIP + $this->typeId, $spillover->getFoundIDs() ?: [0], + $this->typeId, $spillover->getFoundIDs() ?: [0] ); if ($cRep) @@ -303,13 +303,13 @@ class FactionBaseResponse extends TemplateResponse implements ICache // tab: quests $conditions = array( - 'OR', + DB::OR, Listview::DEFAULT_SIZE, - ['AND', ['rewardFactionId1', $this->typeId], ['rewardFactionValue1', 0, '>']], - ['AND', ['rewardFactionId2', $this->typeId], ['rewardFactionValue2', 0, '>']], - ['AND', ['rewardFactionId3', $this->typeId], ['rewardFactionValue3', 0, '>']], - ['AND', ['rewardFactionId4', $this->typeId], ['rewardFactionValue4', 0, '>']], - ['AND', ['rewardFactionId5', $this->typeId], ['rewardFactionValue5', 0, '>']] + [DB::AND, ['rewardFactionId1', $this->typeId], ['rewardFactionValue1', 0, '>']], + [DB::AND, ['rewardFactionId2', $this->typeId], ['rewardFactionValue2', 0, '>']], + [DB::AND, ['rewardFactionId3', $this->typeId], ['rewardFactionValue3', 0, '>']], + [DB::AND, ['rewardFactionId4', $this->typeId], ['rewardFactionValue4', 0, '>']], + [DB::AND, ['rewardFactionId5', $this->typeId], ['rewardFactionValue5', 0, '>']] ); $quests = new QuestList($conditions, ['calcTotal' => true]); if (!$quests->error) diff --git a/endpoints/factions/factions.php b/endpoints/factions/factions.php index b415d933..5e8dd308 100644 --- a/endpoints/factions/factions.php +++ b/endpoints/factions/factions.php @@ -81,11 +81,11 @@ class FactionsBaseResponse extends TemplateResponse implements ICache else if (isset($this->category[0])) { if ($this->category[0]) - $subs = DB::Aowow()->selectCol('SELECT `id` FROM ?_factions WHERE `parentFactionId` = ?d', $this->category[0]); + $subs = DB::Aowow()->selectCol('SELECT `id` FROM ::factions WHERE `parentFactionId` = %i', $this->category[0]); else $subs = [0]; - $conditions[] = ['OR', ['parentFactionId', $subs], ['id', $subs]]; + $conditions[] = [DB::OR, ['parentFactionId', $subs], ['id', $subs]]; } $data = []; diff --git a/endpoints/go-to-comment/go-to-comment.php b/endpoints/go-to-comment/go-to-comment.php index 6c558d65..c99d55f4 100644 --- a/endpoints/go-to-comment/go-to-comment.php +++ b/endpoints/go-to-comment/go-to-comment.php @@ -23,7 +23,7 @@ class GotocommentBaseResponse extends TextResponse // the reputation-history listview only creates go-to-comment links. So either upvoting replies does not grant reputation, or.... bug.? - $comment = DB::Aowow()->selectRow('SELECT IFNULL(c2.`id`, c1.`id`) AS "id", IFNULL(c2.`type`, c1.`type`) AS "type", IFNULL(c2.`typeId`, c1.`typeId`) AS "typeId" FROM ?_comments c1 LEFT JOIN ?_comments c2 ON c1.`replyTo` = c2.`id` WHERE c1.`id` = ?d', $this->_get['id']); + $comment = DB::Aowow()->selectRow('SELECT IFNULL(c2.`id`, c1.`id`) AS "id", IFNULL(c2.`type`, c1.`type`) AS "type", IFNULL(c2.`typeId`, c1.`typeId`) AS "typeId" FROM ::comments c1 LEFT JOIN ::comments c2 ON c1.`replyTo` = c2.`id` WHERE c1.`id` = %i', $this->_get['id']); if (!$comment) { trigger_error('GotocommentBaseResponse - comment #'.$this->_get['id'].' not found', E_USER_ERROR); diff --git a/endpoints/go-to-reply/go-to-reply.php b/endpoints/go-to-reply/go-to-reply.php index c13fdebd..e3cbbcc4 100644 --- a/endpoints/go-to-reply/go-to-reply.php +++ b/endpoints/go-to-reply/go-to-reply.php @@ -22,7 +22,7 @@ class GotoreplyBaseResponse extends TextResponse } // type = typeId = 0 AND replyTo <> 0 for replies - $reply = DB::Aowow()->selectRow('SELECT c.`id`, r.`id` AS "reply", c.`type`, c.`typeId` FROM ?_comments r JOIN ?_comments c ON r.`replyTo` = c.`id` WHERE r.`id` = ?d', $this->_get['id']); + $reply = DB::Aowow()->selectRow('SELECT c.`id`, r.`id` AS "reply", c.`type`, c.`typeId` FROM ::comments r JOIN ::comments c ON r.`replyTo` = c.`id` WHERE r.`id` = %i', $this->_get['id']); if (!$reply) { trigger_error('GotoreplyBaseResponse - reply #'.$this->_get['id'].' not found', E_USER_ERROR); diff --git a/endpoints/guide/changelog.php b/endpoints/guide/changelog.php index aa41d802..eee823e7 100644 --- a/endpoints/guide/changelog.php +++ b/endpoints/guide/changelog.php @@ -81,7 +81,7 @@ class GuideChangelogResponse extends TemplateResponse $inp = fn($rev) => User::isInGroup(U_GROUP_STAFF) && false ? ($rev !== null ? '' : '') : ''; $now = new DateTime(); - $logEntries = DB::Aowow()->select('SELECT a.`username` AS `name`, gcl.`date`, gcl.`status`, gcl.`msg`, gcl.`rev` FROM ?_guides_changelog gcl JOIN ?_account a ON a.`id` = gcl.`userId` WHERE gcl.`id` = ?d ORDER BY gcl.`date` DESC', $this->_get['id']); + $logEntries = DB::Aowow()->selectAssoc('SELECT a.`username` AS `name`, gcl.`date`, gcl.`status`, gcl.`msg`, gcl.`rev` FROM ::guides_changelog gcl JOIN ::account a ON a.`id` = gcl.`userId` WHERE gcl.`id` = %i ORDER BY gcl.`date` DESC', $this->_get['id']); foreach ($logEntries as $log) { if ($log['status'] != GuideMgr::STATUS_NONE) diff --git a/endpoints/guide/edit.php b/endpoints/guide/edit.php index 9f7af2b2..be86d440 100644 --- a/endpoints/guide/edit.php +++ b/endpoints/guide/edit.php @@ -66,7 +66,7 @@ class GuideEditResponse extends TemplateResponse return; $this->typeId = $this->_get['id']; // just to display sensible not-found msg - $status = DB::Aowow()->selectCell('SELECT `status` FROM ?_guides WHERE `id` = ?d AND `status` <> ?d { AND `userId` = ?d }', $this->typeId, GuideMgr::STATUS_ARCHIVED, User::isInGroup(U_GROUP_STAFF) ? DBSIMPLE_SKIP : User::$id); + $status = DB::Aowow()->selectCell('SELECT `status` FROM ::guides WHERE %if', !User::isInGroup(U_GROUP_STAFF), '`userId` = %i AND', User::$id, '%end `id` = %i AND `status` <> %i', $this->typeId, GuideMgr::STATUS_ARCHIVED); if (!$status && $this->typeId) $this->generateNotFound(Lang::game('guide'), Lang::guide('notFound')); else if (!$this->typeId) @@ -75,7 +75,7 @@ class GuideEditResponse extends TemplateResponse // just so we don't have to access GuideMgr from template $this->isDraft = $status == GuideMgr::STATUS_DRAFT; $this->editStatus = $status; - $this->editRev = DB::Aowow()->selectCell('SELECT `rev` FROM ?_articles WHERE `type` = ?d AND `typeId` = ?d ORDER BY `rev` DESC', Type::GUIDE, $this->typeId); + $this->editRev = DB::Aowow()->selectCell('SELECT `rev` FROM ::articles WHERE `type` = %i AND `typeId` = %i ORDER BY `rev` DESC', Type::GUIDE, $this->typeId); } protected function generate() : void @@ -157,15 +157,15 @@ class GuideEditResponse extends TemplateResponse if ($this->_get['id'] === 0) { $guideData += ['userId' => User::$id]; - if (!($this->typeId = (int)DB::Aowow()->query('INSERT INTO ?_guides (?#) VALUES (?a)', array_keys($guideData), array_values($guideData)))) + if (!($this->typeId = (int)DB::Aowow()->qry('INSERT INTO ::guides %v', $guideData))) { trigger_error('GuideEditResponse::saveGuide - failed to save guide to db', E_USER_ERROR); return false; } } // existing guide > :shrug: - else if (DB::Aowow()->query('UPDATE ?_guides SET ?a WHERE `id` = ?d', $guideData, $this->typeId)) - DB::Aowow()->query('INSERT INTO ?_guides_changelog (`id`, `rev`, `date`, `userId`, `msg`) VALUES (?d, ?d, ?d, ?d, ?)', $this->typeId, $this->editRev, time(), User::$id, $this->_post['changelog']); + else if (DB::Aowow()->qry('UPDATE ::guides SET %a WHERE `id` = %i', $guideData, $this->typeId)) + DB::Aowow()->qry('INSERT INTO ::guides_changelog (`id`, `rev`, `date`, `userId`, `msg`) VALUES (%i, %i, %i, %i, %s)', $this->typeId, $this->editRev, time(), User::$id, $this->_post['changelog']); else { trigger_error('GuideEditResponse::saveGuide - failed to update guide in db', E_USER_ERROR); @@ -173,8 +173,8 @@ class GuideEditResponse extends TemplateResponse } // insert Article - $articleId = DB::Aowow()->query( - 'INSERT INTO ?_articles (`type`, `typeId`, `locale`, `rev`, `editAccess`, `article`) VALUES (?d, ?d, ?d, ?d, ?d, ?)', + $articleId = DB::Aowow()->qry( + 'INSERT INTO ::articles (`type`, `typeId`, `locale`, `rev`, `editAccess`, `article`) VALUES (%i, %i, %i, %i, %i, %s)', Type::GUIDE, $this->typeId, $this->_post['locale']->value, @@ -186,14 +186,14 @@ class GuideEditResponse extends TemplateResponse if (!is_int($articleId)) { if ($this->_get['id'] === 0) - DB::Aowow()->query('DELETE FROM ?_guides WHERE `id` = ?d', $this->typeId); + DB::Aowow()->qry('DELETE FROM ::guides WHERE `id` = %i', $this->typeId); trigger_error('GuideEditResponse::saveGuide - failed to save article to db', E_USER_ERROR); return false; } if ($this->_post['submit'] && $this->editStatus != GuideMgr::STATUS_REVIEW) - DB::Aowow()->query('INSERT INTO ?_guides_changelog (`id`, `date`, `userId`, `status`) VALUES (?d, ?d, ?d, ?d)', $this->typeId, time(), User::$id, GuideMgr::STATUS_REVIEW); + DB::Aowow()->qry('INSERT INTO ::guides_changelog (`id`, `date`, `userId`, `status`) VALUES (%i, %i, %i, %i)', $this->typeId, time(), User::$id, GuideMgr::STATUS_REVIEW); $this->editStatus = $guideData['status']; diff --git a/endpoints/guide/guide.php b/endpoints/guide/guide.php index 215bdb53..45e30c07 100644 --- a/endpoints/guide/guide.php +++ b/endpoints/guide/guide.php @@ -42,7 +42,7 @@ class GuideBaseResponse extends TemplateResponse implements ICache $this->typeId = $nameOrId; else if (preg_match(GuideMgr::VALID_URL, $nameOrId)) { - if ($id = DB::Aowow()->selectCell('SELECT `id` FROM ?_guides WHERE `url` = ?', Util::lower($nameOrId))) + if ($id = DB::Aowow()->selectCell('SELECT `id` FROM ::guides WHERE `url` = %s', Util::lower($nameOrId))) { $this->typeId = intVal($id); $this->articleUrl = Util::lower($nameOrId); @@ -215,9 +215,9 @@ class GuideBaseResponse extends TemplateResponse implements ICache return; // increment and display views - DB::Aowow()->query('UPDATE ?_guides SET `views` = `views` + 1 WHERE `id` = ?d', $pt->typeId); + DB::Aowow()->qry('UPDATE ::guides SET `views` = `views` + 1 WHERE `id` = %i', $pt->typeId); - $nViews = DB::Aowow()->selectCell('SELECT `views` FROM ?_guides WHERE `id` = ?d', $pt->typeId); + $nViews = DB::Aowow()->selectCell('SELECT `views` FROM ::guides WHERE `id` = %i', $pt->typeId); $infobox->addItem(Lang::guide('views').'[n5='.$nViews.']'); diff --git a/endpoints/guide/guide_power.php b/endpoints/guide/guide_power.php index 99fd4dba..970bc302 100644 --- a/endpoints/guide/guide_power.php +++ b/endpoints/guide/guide_power.php @@ -32,7 +32,7 @@ class GuidePowerResponse extends TextResponse implements ICache if (Util::checkNumeric($idOrName, NUM_CAST_INT)) $this->typeId = $idOrName; - else if ($id = DB::Aowow()->selectCell('SELECT `id` FROM ?_guides WHERE `url` = ?', Util::lower($idOrName))) + else if ($id = DB::Aowow()->selectCell('SELECT `id` FROM ::guides WHERE `url` = %s', Util::lower($idOrName))) { $this->typeId = intVal($id); $this->url = Util::lower($idOrName); diff --git a/endpoints/guide/vote.php b/endpoints/guide/vote.php index ca7ee945..ff82c837 100644 --- a/endpoints/guide/vote.php +++ b/endpoints/guide/vote.php @@ -29,18 +29,18 @@ class GuideVoteResponse extends TextResponse // by id, not own, published $points = $votes = 0; - if ($g = DB::Aowow()->selectRow('SELECT `userId`, `cuFlags` FROM ?_guides WHERE `id` = ?d AND (`status` = ?d OR `rev` > 0)', $this->_post['id'], GuideMgr::STATUS_APPROVED)) + if ($g = DB::Aowow()->selectRow('SELECT `userId`, `cuFlags` FROM ::guides WHERE `id` = %i AND (`status` = %i OR `rev` > 0)', $this->_post['id'], GuideMgr::STATUS_APPROVED)) { // apparently you are allowed to vote on your own guide if ($g['cuFlags'] & GUIDE_CU_NO_RATING) $this->generate403(); if (!$this->_post['rating']) - DB::Aowow()->query('DELETE FROM ?_user_ratings WHERE `type` = ?d AND `entry` = ?d AND `userId` = ?d', RATING_GUIDE, $this->_post['id'], User::$id); + DB::Aowow()->qry('DELETE FROM ::user_ratings WHERE `type` = %i AND `entry` = %i AND `userId` = %i', RATING_GUIDE, $this->_post['id'], User::$id); else - DB::Aowow()->query('REPLACE INTO ?_user_ratings (`type`, `entry`, `userId`, `value`) VALUES (?d, ?d, ?d, ?d)', RATING_GUIDE, $this->_post['id'], User::$id, $this->_post['rating']); + DB::Aowow()->qry('REPLACE INTO ::user_ratings (`type`, `entry`, `userId`, `value`) VALUES (%i, %i, %i, %i)', RATING_GUIDE, $this->_post['id'], User::$id, $this->_post['rating']); - [$points, $votes] = DB::Aowow()->selectRow('SELECT IFNULL(SUM(`value`), 0) AS "0", IFNULL(COUNT(*), 0) AS "1" FROM ?_user_ratings WHERE `type` = ?d AND `entry` = ?d', RATING_GUIDE, $this->_post['id']); + [$points, $votes] = DB::Aowow()->selectRow('SELECT IFNULL(SUM(`value`), 0) AS "0", IFNULL(COUNT(*), 0) AS "1" FROM ::user_ratings WHERE `type` = %i AND `entry` = %i', RATING_GUIDE, $this->_post['id']); } $this->result = Util::toJSON($votes ? ['rating' => $points / $votes, 'nvotes' => $votes] : ['rating' => 0, 'nvotes' => 0]); diff --git a/endpoints/guides/guides.php b/endpoints/guides/guides.php index cff1b489..23116f41 100644 --- a/endpoints/guides/guides.php +++ b/endpoints/guides/guides.php @@ -45,7 +45,7 @@ class GuidesBaseResponse extends TemplateResponse // implements ICache ['locale', Lang::getLocale()->value], ['status', GuideMgr::STATUS_ARCHIVED, '!'], // never archived guides [ - 'OR', + DB::OR, ['status', GuideMgr::STATUS_APPROVED], // currently approved ['rev', 0, '>'] // has previously approved revision ] diff --git a/endpoints/guild/guild.php b/endpoints/guild/guild.php index 7c74b2aa..9db0d252 100644 --- a/endpoints/guild/guild.php +++ b/endpoints/guild/guild.php @@ -46,7 +46,7 @@ class GuildBaseResponse extends TemplateResponse // 3 possibilities // 1) already synced to aowow - if ($subject = DB::Aowow()->selectRow('SELECT `id`, `realmGUID`, `stub` 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` = %i AND `nameUrl` = %s', $this->realmId, Profiler::urlize($this->subjectName))) { $this->typeId = $subject['id']; @@ -57,16 +57,15 @@ class GuildBaseResponse extends TemplateResponse } // 2) not yet synced but exists on realm (wont work if we get passed an urlized name, but there is nothing we can do about it) - $subjects = DB::Characters($this->realmId)->select('SELECT `guildid` AS "realmGUID", `name` FROM guild WHERE `name` = ?', $this->subjectName); - if ($subject = array_filter($subjects ?: [], fn($x) => Util::lower($x['name']) === Util::lower($this->subjectName))) + $subjects = DB::Characters($this->realmId)->selectAssoc('SELECT `guildid` AS "realmGUID", `name` FROM guild WHERE `name` = %s', $this->subjectName); + if ($subject = array_find($subjects ?: [], fn($x) => Util::lower($x['name']) === Util::lower($this->subjectName))) { - $subject = array_pop($subject); $subject['realm'] = $this->realmId; $subject['stub'] = 1; $subject['nameUrl'] = Profiler::urlize($subject['name']); // create entry from realm with basic info - DB::Aowow()->query('INSERT IGNORE INTO ?_profiler_guild (?#) VALUES (?a)', array_keys($subject), array_values($subject)); + DB::Aowow()->qry('INSERT IGNORE INTO ::profiler_guild %v', $subject); $this->handleIncompleteData(Type::GUILD, $subject['realmGUID']); return; @@ -122,7 +121,7 @@ class GuildBaseResponse extends TemplateResponse // statistic calculations here // smuggle the guild ranks into the html - if ($ranks = DB::Aowow()->selectCol('SELECT `rank` AS ARRAY_KEY, `name` FROM ?_profiler_guild_rank WHERE `guildId` = ?d', $this->typeId)) + if ($ranks = DB::Aowow()->selectCol('SELECT `rank` AS ARRAY_KEY, `name` FROM ::profiler_guild_rank WHERE `guildId` = %i', $this->typeId)) $this->extraHTML = ''; diff --git a/endpoints/guild/resync.php b/endpoints/guild/resync.php index deddcbde..82df7f8f 100644 --- a/endpoints/guild/resync.php +++ b/endpoints/guild/resync.php @@ -32,12 +32,12 @@ class GuildResyncResponse extends TextResponse if (!$this->assertGET('id')) return; - if ($guilds = DB::Aowow()->select('SELECT `realm`, `realmGUID` FROM ?_profiler_guild WHERE `id` IN (?a)', $this->_get['id'])) + if ($guilds = DB::Aowow()->selectAssoc('SELECT `realm`, `realmGUID` FROM ::profiler_guild WHERE `id` IN %in', $this->_get['id'])) foreach ($guilds as $g) Profiler::scheduleResync(Type::GUILD, $g['realm'], $g['realmGUID']); if ($this->_get['profile']) - if ($chars = DB::Aowow()->select('SELECT `realm`, `realmGUID` FROM ?_profiler_profiles WHERE `guild` IN (?a)', $this->_get['id'])) + if ($chars = DB::Aowow()->selectAssoc('SELECT `realm`, `realmGUID` FROM ::profiler_profiles WHERE `guild` IN %in', $this->_get['id'])) foreach ($chars as $c) Profiler::scheduleResync(Type::PROFILE, $c['realm'], $c['realmGUID']); diff --git a/endpoints/home/home.php b/endpoints/home/home.php index 4dd0c69f..8ca0caba 100644 --- a/endpoints/home/home.php +++ b/endpoints/home/home.php @@ -25,18 +25,18 @@ class HomeBaseResponse extends TemplateResponse protected function generate() : void { // set element - if ($_ = DB::Aowow()->selectCell('SELECT `title` FROM ?_home_titles WHERE `active` = 1 AND `locale` = ?d ORDER BY RAND()', Lang::getLocale()->value)) + if ($_ = DB::Aowow()->selectCell('SELECT `title` FROM ::home_titles WHERE `active` = 1 AND `locale` = %i ORDER BY RAND()', Lang::getLocale()->value)) $this->homeTitle = Util::jsEscape(Cfg::get('NAME').Lang::main('colon').$_); // load oneliner - if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_home_oneliner WHERE `active` = 1 ORDER BY RAND() LIMIT 1')) + if ($_ = DB::Aowow()->selectRow('SELECT * FROM ::home_oneliner WHERE `active` = 1 ORDER BY RAND() LIMIT 1')) $this->oneliner = new Markup(new LocString($_, 'text'), [], 'home-oneliner'); if ($_ = $this->oneliner?->getJsGlobals()) $this->extendGlobalData($_); // load featuredBox (user web server time) - if ($box = DB::Aowow()->selectRow('SELECT * FROM ?_home_featuredbox WHERE ?d BETWEEN `startDate` AND `endDate` ORDER BY `id` DESC', time())) + if ($box = DB::Aowow()->selectRow('SELECT * FROM ::home_featuredbox WHERE %i BETWEEN `startDate` AND `endDate` ORDER BY `id` DESC', time())) { // define text constants for all fields (STATIC_URL, HOST_URL, etc.) $box = Util::defStatic($box); @@ -55,9 +55,9 @@ class HomeBaseResponse extends TemplateResponse $this->extendGlobalData($_); // load overlay links - foreach (DB::Aowow()->select('SELECT * FROM ?_home_featuredbox_overlay WHERE `featureId` = ?d', $box['id']) as $ovl) + foreach (DB::Aowow()->selectAssoc('SELECT * FROM ::home_featuredbox_overlay WHERE `featureId` = %i', $box['id']) as $ovl) { - $ovl = Util::defStatic($ovl); + $ovl = Util::defStatic((array)$ovl); $this->featuredBox['overlays'][] = array( 'url' => $ovl['url'], diff --git a/endpoints/icon/get-id-from-name.php b/endpoints/icon/get-id-from-name.php index 178602cc..a74d9f62 100644 --- a/endpoints/icon/get-id-from-name.php +++ b/endpoints/icon/get-id-from-name.php @@ -21,7 +21,7 @@ class IconGetidfromnameResponse extends TextResponse } $this->result = 0; - if ($id = DB::Aowow()->selectCell('SELECT `id` FROM ?_icons WHERE `name` = ?', $this->_get['name'])) + if ($id = DB::Aowow()->selectCell('SELECT `id` FROM ::icons WHERE `name` = %s', $this->_get['name'])) $this->result = $id; } } diff --git a/endpoints/item/item.php b/endpoints/item/item.php index 1f9f4123..87778919 100644 --- a/endpoints/item/item.php +++ b/endpoints/item/item.php @@ -144,7 +144,7 @@ class ItemBaseResponse extends TemplateResponse implements ICache // tool if ($tId = $this->subject->getField('totemCategory')) - if ($tName = DB::Aowow()->selectRow('SELECT * FROM ?_totemcategory WHERE `id` = ?d', $tId)) + if ($tName = DB::Aowow()->selectRow('SELECT * FROM ::totemcategory WHERE `id` = %i', $tId)) $infobox[] = Lang::item('tool').'[url=?items&filter=cr=91;crs='.$tId.';crv=0]'.Util::localizedString($tName, 'name').'[/url]'; // extendedCost @@ -396,7 +396,7 @@ class ItemBaseResponse extends TemplateResponse implements ICache } // factionchange-equivalent - if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = ?d, `alliance_id`, -`horde_id`) FROM player_factionchange_items WHERE `alliance_id` = ?d OR `horde_id` = ?d', $this->typeId, $this->typeId, $this->typeId)) + if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = %i, `alliance_id`, -`horde_id`) FROM player_factionchange_items WHERE `alliance_id` = %i OR `horde_id` = %i', $this->typeId, $this->typeId, $this->typeId)) { $altItem = new ItemList(array(['id', abs($pendant)])); if (!$altItem->error) @@ -420,7 +420,7 @@ class ItemBaseResponse extends TemplateResponse implements ICache $this->lvTabs = new Tabs(['parent' => "\$\$WH.ge('tabs-generic')"], 'tabsRelated', true); // tab: createdBy (perfect item specific) - if ($perfItem = DB::World()->select('SELECT *, `spellId` AS ARRAY_KEY FROM skill_perfect_item_template WHERE `perfectItemType` = ?d', $this->typeId)) + if ($perfItem = DB::World()->selectAssoc('SELECT *, `spellId` AS ARRAY_KEY FROM skill_perfect_item_template WHERE `perfectItemType` = %i', $this->typeId)) { $perfSpells = new SpellList(array(['id', array_column($perfItem, 'spellId')])); if (!$perfSpells->error) @@ -630,7 +630,7 @@ class ItemBaseResponse extends TemplateResponse implements ICache // tab: reagent for $conditions = array( - 'OR', + DB::OR, ['reagent1', $this->typeId], ['reagent2', $this->typeId], ['reagent3', $this->typeId], ['reagent4', $this->typeId], ['reagent5', $this->typeId], ['reagent6', $this->typeId], ['reagent7', $this->typeId], ['reagent8', $this->typeId] ); @@ -650,9 +650,9 @@ class ItemBaseResponse extends TemplateResponse implements ICache // tab: unlocks (object or item) $lockIds = DB::Aowow()->selectCol( - 'SELECT `id` FROM ?_lock WHERE (`type1` = ?d AND `properties1` = ?d) OR - (`type2` = ?d AND `properties2` = ?d) OR (`type3` = ?d AND `properties3` = ?d) OR - (`type4` = ?d AND `properties4` = ?d) OR (`type5` = ?d AND `properties5` = ?d)', + 'SELECT `id` FROM ::lock WHERE (`type1` = %i AND `properties1` = %i) OR + (`type2` = %i AND `properties2` = %i) OR (`type3` = %i AND `properties3` = %i) OR + (`type4` = %i AND `properties4` = %i) OR (`type5` = %i AND `properties5` = %i)', LOCK_TYPE_ITEM, $this->typeId, LOCK_TYPE_ITEM, $this->typeId, LOCK_TYPE_ITEM, $this->typeId, LOCK_TYPE_ITEM, $this->typeId, LOCK_TYPE_ITEM, $this->typeId @@ -704,7 +704,7 @@ class ItemBaseResponse extends TemplateResponse implements ICache // tab: objective of (quest) $conditions = array( - 'OR', + DB::OR, ['reqItemId1', $this->typeId], ['reqItemId2', $this->typeId], ['reqItemId3', $this->typeId], ['reqItemId4', $this->typeId], ['reqItemId5', $this->typeId], ['reqItemId6', $this->typeId] ); @@ -722,7 +722,7 @@ class ItemBaseResponse extends TemplateResponse implements ICache // tab: provided for (quest) $conditions = array( - 'OR', ['sourceItemId', $this->typeId], + DB::OR, ['sourceItemId', $this->typeId], ['reqSourceItemId1', $this->typeId], ['reqSourceItemId2', $this->typeId], ['reqSourceItemId3', $this->typeId], ['reqSourceItemId4', $this->typeId] ); @@ -838,8 +838,8 @@ class ItemBaseResponse extends TemplateResponse implements ICache if (!$n && !is_null(ItemListFilter::getCriteriaIndex(158, $this->typeId))) $n = '?items&filter=cr=158;crs='.$this->typeId.';crv=0'; - $xCosts = DB::Aowow()->selectCol('SELECT `id` FROM ?_itemextendedcost WHERE '.$w); - $boughtBy = $xCosts ? DB::World()->selectCol('SELECT `item` FROM npc_vendor WHERE `extendedCost` IN (?a) UNION SELECT `item` FROM game_event_npc_vendor WHERE `extendedCost` IN (?a)', $xCosts, $xCosts) : null; + $xCosts = DB::Aowow()->selectCol('SELECT `id` FROM ::itemextendedcost WHERE '.$w); + $boughtBy = $xCosts ? DB::World()->selectCol('SELECT `item` FROM npc_vendor WHERE `extendedCost` IN %in UNION SELECT `item` FROM game_event_npc_vendor WHERE `extendedCost` IN %in', $xCosts, $xCosts) : null; if ($boughtBy) { $boughtBy = new ItemList(array(['id', $boughtBy])); @@ -910,10 +910,10 @@ class ItemBaseResponse extends TemplateResponse implements ICache $conditions = array( ['id', $this->typeId, '!'], [ - 'OR', + DB::OR, ['name_loc'.Lang::getLocale()->value, $this->subject->getField('name', true)], [ - 'AND', + DB::AND, ['class', $_class], ['subClass', $_subClass], ['slot', $_slot], @@ -926,7 +926,7 @@ class ItemBaseResponse extends TemplateResponse implements ICache ); if ($_ = $this->subject->getField('itemset')) - $conditions[1][] = ['AND', ['slot', $_slot], ['itemset', $_]]; + $conditions[1][] = [DB::AND, ['slot', $_slot], ['itemset', $_]]; $saItems = new ItemList($conditions); if (!$saItems->error) @@ -972,7 +972,7 @@ class ItemBaseResponse extends TemplateResponse implements ICache $useSpells[] = $this->subject->getField('spellId'.$i); } if ($useSpells) - if ($_ = DB::Aowow()->selectCol('SELECT `category` FROM ?_spell WHERE `id` IN (?a) AND `recoveryCategory` > 0', $useSpells)) + if ($_ = DB::Aowow()->selectCol('SELECT `category` FROM ::spell WHERE `id` IN %in AND `recoveryCategory` > 0', $useSpells)) $cdCats += $_; if ($cdCats) @@ -980,7 +980,7 @@ class ItemBaseResponse extends TemplateResponse implements ICache $conditions = array( ['id', $this->typeId, '!'], [ - 'OR', + DB::OR, ['spellCategory1', $cdCats], ['spellCategory2', $cdCats], ['spellCategory3', $cdCats], @@ -989,7 +989,7 @@ class ItemBaseResponse extends TemplateResponse implements ICache ] ); - if ($spellsByCat = DB::Aowow()->selectCol('SELECT `id` FROM ?_spell WHERE `category` IN (?a)', $cdCats)) + if ($spellsByCat = DB::Aowow()->selectCol('SELECT `id` FROM ::spell WHERE `category` IN %in', $cdCats)) for ($i = 1; $i < 6; $i++) $conditions[1][] = ['spellId'.$i, $spellsByCat]; @@ -1014,7 +1014,7 @@ class ItemBaseResponse extends TemplateResponse implements ICache if ($this->subject->getField('soundOverrideSubclass') > 0) $scm = (1 << $this->subject->getField('soundOverrideSubclass')); - $soundIds = DB::Aowow()->selectCol('SELECT `soundId` FROM ?_items_sounds WHERE `subClassMask` & ?d', $scm); + $soundIds = DB::Aowow()->selectCol('SELECT `soundId` FROM ::items_sounds WHERE `subClassMask` & %i', $scm); } $fields = ['pickUpSoundId', 'dropDownSoundId', 'sheatheSoundId', 'unsheatheSoundId']; @@ -1024,7 +1024,7 @@ class ItemBaseResponse extends TemplateResponse implements ICache if ($x = $this->subject->getField('spellVisualId')) { - if ($spellSounds = DB::Aowow()->selectRow('SELECT * FROM ?_spell_sounds WHERE `id` = ?d', $x)) + if ($spellSounds = DB::Aowow()->selectRow('SELECT * FROM ::spell_sounds WHERE `id` = %i', $x)) { array_shift($spellSounds); // bye 'id'-field foreach ($spellSounds as $ss) diff --git a/endpoints/item/item_xml.php b/endpoints/item/item_xml.php index 6a06851b..19997124 100644 --- a/endpoints/item/item_xml.php +++ b/endpoints/item/item_xml.php @@ -148,10 +148,10 @@ class ItemXmlResponse extends TextResponse implements ICache // reagents $cnd = array( - 'OR', - ['AND', ['effect1CreateItemId', $this->typeId], ['OR', ['effect1Id', SpellList::EFFECTS_ITEM_CREATE], ['effect1AuraId', SpellList::AURAS_ITEM_CREATE]]], - ['AND', ['effect2CreateItemId', $this->typeId], ['OR', ['effect2Id', SpellList::EFFECTS_ITEM_CREATE], ['effect2AuraId', SpellList::AURAS_ITEM_CREATE]]], - ['AND', ['effect3CreateItemId', $this->typeId], ['OR', ['effect3Id', SpellList::EFFECTS_ITEM_CREATE], ['effect3AuraId', SpellList::AURAS_ITEM_CREATE]]], + DB::OR, + [DB::AND, ['effect1CreateItemId', $this->typeId], [DB::OR, ['effect1Id', SpellList::EFFECTS_ITEM_CREATE], ['effect1AuraId', SpellList::AURAS_ITEM_CREATE]]], + [DB::AND, ['effect2CreateItemId', $this->typeId], [DB::OR, ['effect2Id', SpellList::EFFECTS_ITEM_CREATE], ['effect2AuraId', SpellList::AURAS_ITEM_CREATE]]], + [DB::AND, ['effect3CreateItemId', $this->typeId], [DB::OR, ['effect3Id', SpellList::EFFECTS_ITEM_CREATE], ['effect3AuraId', SpellList::AURAS_ITEM_CREATE]]], ); $spellSource = new SpellList($cnd); diff --git a/endpoints/items/items.php b/endpoints/items/items.php index 88ed9ca8..0f5f48fd 100644 --- a/endpoints/items/items.php +++ b/endpoints/items/items.php @@ -289,7 +289,7 @@ class ItemsBaseResponse extends TemplateResponse implements ICache case ItemListFilter::GROUP_BY_LEVEL: // itemlevel: first, try to find 10 level steps within range (if given) as tabs // ohkayy, maybe i need to rethink $this $this->filterOpts = $this->filter->extraOpts; - $this->filterOpts['is']['o'] = [null]; // remove 'order by' from ?_item_stats + $this->filterOpts['is']['o'] = [null]; // remove 'order by' from ::item_stats $extraOpts = array_merge($this->filterOpts, ['i' => ['g' => ['itemlevel'], 'o' => ['itemlevel DESC']]]); $levelRef = new ItemList(array_merge($conditions, [10]), ['extraOpts' => $extraOpts]); diff --git a/endpoints/mail/mail.php b/endpoints/mail/mail.php index 41c20c3d..0b6fe31b 100644 --- a/endpoints/mail/mail.php +++ b/endpoints/mail/mail.php @@ -63,13 +63,13 @@ class MailBaseResponse extends TemplateResponse implements ICache // sender + delay if ($this->typeId < 0) // def. achievement { - if ($npcId = DB::World()->selectCell('SELECT `Sender` FROM achievement_reward WHERE `ID` = ?d', -$this->typeId)) + if ($npcId = DB::World()->selectCell('SELECT `Sender` FROM achievement_reward WHERE `ID` = %i', -$this->typeId)) { $infobox[] = Lang::mail('sender', ['[npc='.$npcId.']']); $this->extendGlobalIds(Type::NPC, $npcId); } } - else if ($mlr = DB::World()->selectRow('SELECT * FROM mail_level_reward WHERE `mailTemplateId` = ?d', $this->typeId)) // level rewards + else if ($mlr = DB::World()->selectRow('SELECT * FROM mail_level_reward WHERE `mailTemplateId` = %i', $this->typeId)) // level rewards { if ($mlr['level']) $infobox[] = Lang::game('level').Lang::main('colon').$mlr['level']; @@ -87,14 +87,14 @@ class MailBaseResponse extends TemplateResponse implements ICache } else // achievement or quest { - if ($q = DB::Aowow()->selectRow('SELECT `id`, `rewardMailDelay` FROM ?_quests WHERE `rewardMailTemplateId` = ?d', $this->typeId)) + if ($q = DB::Aowow()->selectRow('SELECT `id`, `rewardMailDelay` FROM ::quests WHERE `rewardMailTemplateId` = %i', $this->typeId)) { - if ($npcId= DB::World()->selectCell('SELECT `RewardMailSenderEntry` FROM quest_mail_sender WHERE `QuestId` = ?d', $q['id'])) + if ($npcId= DB::World()->selectCell('SELECT `RewardMailSenderEntry` FROM quest_mail_sender WHERE `QuestId` = %i', $q['id'])) { $infobox[] = Lang::mail('sender', ['[npc='.$npcId.']']); $this->extendGlobalIds(Type::NPC, $npcId); } - else if ($npcId = DB::Aowow()->selectCell('SELECT `typeId` FROM ?_quests_startend WHERE `questId` = ?d AND `type` = ?d AND `method` & ?d', $q['id'], Type::NPC, 0x2)) + else if ($npcId = DB::Aowow()->selectCell('SELECT `typeId` FROM ::quests_startend WHERE `questId` = %i AND `type` = %i AND `method` & %i', $q['id'], Type::NPC, 0x2)) { $infobox[] = Lang::mail('sender', ['[npc='.$npcId.']']); $this->extendGlobalIds(Type::NPC, $npcId); @@ -103,7 +103,7 @@ class MailBaseResponse extends TemplateResponse implements ICache if ($q['rewardMailDelay'] > 0) $infobox[] = Lang::mail('delay', [DateTime::formatTimeElapsed($q['rewardMailDelay'] * 1000)]); } - else if ($npcId = DB::World()->selectCell('SELECT `Sender` FROM achievement_reward WHERE `MailTemplateId` = ?d', $this->typeId)) + else if ($npcId = DB::World()->selectCell('SELECT `Sender` FROM achievement_reward WHERE `MailTemplateId` = %i', $this->typeId)) { $infobox[] = Lang::mail('sender', ['[npc='.$npcId.']']); $this->extendGlobalIds(Type::NPC, $npcId); @@ -151,7 +151,7 @@ class MailBaseResponse extends TemplateResponse implements ICache } if ($this->typeId < 0 || // used by: achievement - ($acvId = DB::World()->selectCell('SELECT `ID` FROM achievement_reward WHERE `MailTemplateId` = ?d', $this->typeId))) + ($acvId = DB::World()->selectCell('SELECT `ID` FROM achievement_reward WHERE `MailTemplateId` = %i', $this->typeId))) { $ubAchievements = new AchievementList(array(['id', $this->typeId < 0 ? -$this->typeId : $acvId])); if (!$ubAchievements->error) diff --git a/endpoints/most-comments/most-comments.php b/endpoints/most-comments/most-comments.php index f72baec6..20985809 100644 --- a/endpoints/most-comments/most-comments.php +++ b/endpoints/most-comments/most-comments.php @@ -68,8 +68,8 @@ class MostcommentsBaseResponse extends TemplateResponse foreach (Type::getClassesFor() as $type => $classStr) { $comments = DB::Aowow()->selectCol( - 'SELECT `typeId` AS ARRAY_KEY, COUNT(1) FROM ?_comments - WHERE `replyTo` = 0 AND (`flags` & ?d) = 0 AND `type`= ?d AND `date` > (UNIX_TIMESTAMP() - ?d) + 'SELECT `typeId` AS ARRAY_KEY, COUNT(1) FROM ::comments + WHERE `replyTo` = 0 AND (`flags` & %i) = 0 AND `type`= %i AND `date` > (UNIX_TIMESTAMP() - %i) GROUP BY `type`, `typeId` LIMIT 100', CC_FLAG_DELETED, diff --git a/endpoints/most-comments/most-comments_rss.php b/endpoints/most-comments/most-comments_rss.php index 95ae25ea..1f99587d 100644 --- a/endpoints/most-comments/most-comments_rss.php +++ b/endpoints/most-comments/most-comments_rss.php @@ -27,8 +27,8 @@ class MostcommentsRssResponse extends TextResponse foreach (Type::getClassesFor() as $type => $classStr) { $comments = DB::Aowow()->selectCol( - 'SELECT `typeId` AS ARRAY_KEY, COUNT(1) FROM ?_comments - WHERE `replyTo` = 0 AND (`flags` & ?d) = 0 AND `type`= ?d AND `date` > (UNIX_TIMESTAMP() - ?d) + 'SELECT `typeId` AS ARRAY_KEY, COUNT(1) FROM ::comments + WHERE `replyTo` = 0 AND (`flags` & %i) = 0 AND `type`= %i AND `date` > (UNIX_TIMESTAMP() - %i) GROUP BY `type`, `typeId` LIMIT 100', CC_FLAG_DELETED, diff --git a/endpoints/npc/npc.php b/endpoints/npc/npc.php index 58d70edc..1ddf45e5 100644 --- a/endpoints/npc/npc.php +++ b/endpoints/npc/npc.php @@ -90,7 +90,7 @@ class NpcBaseResponse extends TemplateResponse implements ICache $this->altNPCs = new CreatureList(array(['id', array_keys($_altIds)])); } - if ($_ = DB::World()->selectCol('SELECT DISTINCT `entry` FROM vehicle_template_accessory WHERE `accessory_entry` = ?d', $this->typeId)) + if ($_ = DB::World()->selectCol('SELECT DISTINCT `entry` FROM vehicle_template_accessory WHERE `accessory_entry` = %i', $this->typeId)) { $vehicles = new CreatureList(array(['id', $_])); foreach ($vehicles->iterate() as $id => $__) @@ -103,9 +103,9 @@ class NpcBaseResponse extends TemplateResponse implements ICache /**********************/ $mapType = 0; - if ($maps = DB::Aowow()->selectCell('SELECT IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId` = ?d', Type::NPC, $this->typeId)) + if ($maps = DB::Aowow()->selectCell('SELECT IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ::spawns WHERE `type` = %i AND `typeId` = %i', Type::NPC, $this->typeId)) { - $mapType = match ((int)DB::Aowow()->selectCell('SELECT `type` FROM ?_zones WHERE `id` = ?d', $maps[0])) + $mapType = match (DB::Aowow()->selectCell('SELECT `type` FROM ::zones WHERE `id` = %i', $maps)) { // MAP_TYPE_DUNGEON, MAP_TYPE_DUNGEON_HC => 1, @@ -116,13 +116,13 @@ class NpcBaseResponse extends TemplateResponse implements ICache }; } // npc is difficulty dummy: get max difficulty from parent npc - if ($this->placeholder && ($mt = DB::Aowow()->selectCell('SELECT IF(`difficultyEntry1` = ?d, 1, 2) FROM ?_creature WHERE `difficultyEntry1` = ?d OR `difficultyEntry2` = ?d OR `difficultyEntry3` = ?d', $this->typeId, $this->typeId, $this->typeId, $this->typeId))) + if ($this->placeholder && ($mt = DB::Aowow()->selectCell('SELECT IF(`difficultyEntry1` = %i, 1, 2) FROM ::creature WHERE `difficultyEntry1` = %i OR `difficultyEntry2` = %i OR `difficultyEntry3` = %i', $this->typeId, $this->typeId, $this->typeId, $this->typeId))) $mapType = max($mapType, $mt); // npc has difficulty dummys: 2+ dummies -> definitely raid (10/25 + hc); 1 dummy -> may be heroic (used here), but may also be 10/25-raid if ($_altIds) $mapType = max($mapType, count($_altIds) > 1 ? 2 : 1); // for event encounters a single npc may be reused over multiple difficulties but have different chests assigned - if ($d = DB::Aowow()->selectCell('SELECT MAX(`difficulty`) FROM ?_loot_link WHERE `npcId` IN (?a)', array_merge($_altIds, [$this->typeId]))) + if ($d = DB::Aowow()->selectCell('SELECT MAX(`difficulty`) FROM ::loot_link WHERE `npcId` IN %in', array_merge($_altIds, [$this->typeId]))) $mapType = max($mapType, $d > 2 ? 2 : 1); @@ -133,7 +133,7 @@ class NpcBaseResponse extends TemplateResponse implements ICache $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // Event (ignore events, where the object only gets removed) - if ($_ = DB::World()->selectCol('SELECT DISTINCT ge.`eventEntry` FROM game_event ge, game_event_creature gec, creature c WHERE ge.`eventEntry` = gec.`eventEntry` AND c.`guid` = gec.`guid` AND c.`id` = ?d', $this->typeId)) + if ($_ = DB::World()->selectCol('SELECT DISTINCT ge.`eventEntry` FROM game_event ge, game_event_creature gec, creature c WHERE ge.`eventEntry` = gec.`eventEntry` AND c.`guid` = gec.`guid` AND c.`id` = %i', $this->typeId)) { $this->extendGlobalIds(Type::WORLDEVENT, ...$_); $ev = []; @@ -202,7 +202,7 @@ class NpcBaseResponse extends TemplateResponse implements ICache if (User::isInGroup(U_GROUP_EMPLOYEE)) { - $spawnData = DB::Aowow()->select('SELECT `guid` AS "0", `ScriptName` AS "1", `StringId` AS "2" FROM ?_spawns WHERE `type` = ?d AND `typeId` = ?d AND `ScriptName` IS NOT NULL ORDER BY `guid` ASC', Type::NPC, $this->typeId); + $spawnData = DB::Aowow()->selectAssoc('SELECT `guid` AS "0", `ScriptName` AS "1", `StringId` AS "2" FROM ::spawns WHERE `type` = %i AND `typeId` = %i AND `ScriptName` IS NOT NULL ORDER BY `guid` ASC', Type::NPC, $this->typeId); // AI $scripts = null; @@ -318,7 +318,7 @@ class NpcBaseResponse extends TemplateResponse implements ICache if (!$sai->prepare()) // no smartAI found .. check per guid { // at least one of many - $guids = DB::World()->selectCol('SELECT `guid` FROM creature WHERE `id` = ?d', $this->typeId); + $guids = DB::World()->selectCol('SELECT `guid` FROM creature WHERE `id` = %i', $this->typeId); while ($_ = array_pop($guids)) { $sai = new SmartAI(SmartAI::SRC_TYPE_CREATURE, -$_, ['baseEntry' => $this->typeId, 'title' => ' [small](for GUID: '.$_.')[/small]']); @@ -359,7 +359,7 @@ class NpcBaseResponse extends TemplateResponse implements ICache $tplSpells = []; $genSpells = []; $spellClick = []; - $conditions = ['OR']; + $conditions = [DB::OR]; for ($i = 1; $i < 9; $i++) if ($_ = $this->subject->getField('spell'.$i)) @@ -371,7 +371,7 @@ class NpcBaseResponse extends TemplateResponse implements ICache if ($smartSpells = SmartAI::getSpellCastsForOwner($this->typeId, SmartAI::SRC_TYPE_CREATURE)) $genSpells = $smartSpells; - if ($auras = DB::World()->selectCell('SELECT `auras` FROM creature_template_addon WHERE `entry` = ?d', $this->typeId)) + if ($auras = DB::World()->selectCell('SELECT `auras` FROM creature_template_addon WHERE `entry` = %i', $this->typeId)) { $auras = preg_replace('/[^\d ]/', ' ', $auras); // remove erroneous chars from string $genSpells = array_merge($genSpells, array_filter(explode(' ', $auras))); @@ -380,7 +380,7 @@ class NpcBaseResponse extends TemplateResponse implements ICache if ($genSpells) $conditions[] = ['id', $genSpells]; - if ($spellClick = DB::World()->select('SELECT `spell_id` AS ARRAY_KEY, `cast_flags` AS "0", `user_type` AS "1" FROM npc_spellclick_spells WHERE `npc_entry` = ?d', $this->typeId)) + if ($spellClick = DB::World()->selectAssoc('SELECT `spell_id` AS ARRAY_KEY, `cast_flags` AS "0", `user_type` AS "1" FROM npc_spellclick_spells WHERE `npc_entry` = %i', $this->typeId)) { $genSpells = array_merge($genSpells, array_keys($spellClick)); $conditions[] = ['id', array_keys($spellClick)]; @@ -401,13 +401,13 @@ class NpcBaseResponse extends TemplateResponse implements ICache break; } $conditions[] = [ - 'AND', + DB::AND, ['s.typeCat', -3], [ - 'OR', + DB::OR, ['skillLine1', $skill], - ['AND', ['skillLine1', 0, '>'], ['skillLine2OrMask', $skill]], - ['AND', ['skillLine1', -1], ['skillLine2OrMask', $mask, '&']] + [DB::AND, ['skillLine1', 0, '>'], ['skillLine2OrMask', $skill]], + [DB::AND, ['skillLine1', -1], ['skillLine2OrMask', $mask, '&']] ] ]; } @@ -458,10 +458,10 @@ class NpcBaseResponse extends TemplateResponse implements ICache // tab: summoned by [spell] $conditions = array( - 'OR', - ['AND', ['effect1Id', [SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_DEMON]], ['effect1MiscValue', $this->typeId]], - ['AND', ['effect2Id', [SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_DEMON]], ['effect2MiscValue', $this->typeId]], - ['AND', ['effect3Id', [SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_DEMON]], ['effect3MiscValue', $this->typeId]] + DB::OR, + [DB::AND, ['effect1Id', [SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_DEMON]], ['effect1MiscValue', $this->typeId]], + [DB::AND, ['effect2Id', [SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_DEMON]], ['effect2MiscValue', $this->typeId]], + [DB::AND, ['effect3Id', [SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_DEMON]], ['effect3MiscValue', $this->typeId]] ); $sbSpell = new SpellList($conditions); @@ -518,9 +518,9 @@ class NpcBaseResponse extends TemplateResponse implements ICache 'SELECT ts.`SpellId` AS ARRAY_KEY, ts.`MoneyCost` AS "cost", ts.`ReqSkillLine` AS "reqSkillId", ts.`ReqSkillRank` AS "reqSkillValue", ts.`ReqLevel` AS "reqLevel", ts.`ReqAbility1` AS "reqSpellId1", ts.`reqAbility2` AS "reqSpellId2" FROM trainer_spell ts JOIN creature_default_trainer cdt ON cdt.`TrainerId` = ts.`TrainerId` - WHERE cdt.`Creatureid` = ?d'; + WHERE cdt.`Creatureid` = %i'; - if ($tSpells = DB::World()->select($teachQuery, $this->typeId)) + if ($tSpells = DB::World()->selectAssoc($teachQuery, $this->typeId)) { $teaches = new SpellList(array(['id', array_keys($tSpells)])); if (!$teaches->error) @@ -573,9 +573,9 @@ class NpcBaseResponse extends TemplateResponse implements ICache // tab: sells if ($sells = DB::World()->selectCol( - 'SELECT nv.`item` FROM npc_vendor nv WHERE nv.`entry` = ?d UNION - SELECT nv1.`item` FROM npc_vendor nv1 JOIN npc_vendor nv2 ON -nv1.`entry` = nv2.`item` WHERE nv2.`entry` = ?d UNION - SELECT genv.`item` FROM game_event_npc_vendor genv JOIN creature c ON genv.`guid` = c.`guid` WHERE c.`id` = ?d', + 'SELECT nv.`item` FROM npc_vendor nv WHERE nv.`entry` = %i UNION + SELECT nv1.`item` FROM npc_vendor nv1 JOIN npc_vendor nv2 ON -nv1.`entry` = nv2.`item` WHERE nv2.`entry` = %i UNION + SELECT genv.`item` FROM game_event_npc_vendor genv JOIN creature c ON genv.`guid` = c.`guid` WHERE c.`id` = %i', $this->typeId, $this->typeId, $this->typeId) ) { @@ -650,7 +650,7 @@ class NpcBaseResponse extends TemplateResponse implements ICache return 4; // generic case }; - foreach (DB::Aowow()->select('SELECT l.`difficulty` AS ARRAY_KEY, o.`id`, o.`lootId`, o.`name_loc0`, o.`name_loc2`, o.`name_loc3`, o.`name_loc4`, o.`name_loc6`, o.`name_loc8` FROM ?_loot_link l JOIN ?_objects o ON o.`id` = l.`objectId` WHERE l.`npcId` = ?d ORDER BY `difficulty` ASC', $this->typeId) as $difficulty => $lgo) + foreach (DB::Aowow()->selectAssoc('SELECT l.`difficulty` AS ARRAY_KEY, o.`id`, o.`lootId`, o.`name_loc0`, o.`name_loc2`, o.`name_loc3`, o.`name_loc4`, o.`name_loc6`, o.`name_loc8` FROM ::loot_link l JOIN ::objects o ON o.`id` = l.`objectId` WHERE l.`npcId` = %i ORDER BY `difficulty` ASC', $this->typeId) as $difficulty => $lgo) { $sourceFor[1][1][$getBit($mapType, $difficulty)] = $lgo['lootId']; $sourceFor[1][5] = $sourceFor[1][5] ?: '$$WH.sprintf(LANG.lvnote_npcobjectsource, '.$lgo['id'].', "'.Util::localizedString($lgo, 'name').'")'; @@ -673,7 +673,7 @@ class NpcBaseResponse extends TemplateResponse implements ICache foreach ($this->altNPCs->iterate() as $id => $__) { - foreach (DB::Aowow()->select('SELECT l.`difficulty` AS ARRAY_KEY, o.`id`, o.`lootId`, o.`name_loc0`, o.`name_loc2`, o.`name_loc3`, o.`name_loc4`, o.`name_loc6`, o.`name_loc8` FROM ?_loot_link l JOIN ?_objects o ON o.`id` = l.`objectId` WHERE l.`npcId` = ?d ORDER BY `difficulty` ASC', $id) as $difficulty => $lgo) + foreach (DB::Aowow()->selectAssoc('SELECT l.`difficulty` AS ARRAY_KEY, o.`id`, o.`lootId`, o.`name_loc0`, o.`name_loc2`, o.`name_loc3`, o.`name_loc4`, o.`name_loc6`, o.`name_loc8` FROM ::loot_link l JOIN ::objects o ON o.`id` = l.`objectId` WHERE l.`npcId` = %i ORDER BY `difficulty` ASC', $id) as $difficulty => $lgo) { $sourceFor[1][1][$getBit($mapType, $difficulty)] = $lgo['lootId']; $sourceFor[1][5] = $sourceFor[1][5] ?: '$$WH.sprintf(LANG.lvnote_npcobjectsource, '.$lgo['id'].', "'.Util::localizedString($lgo, 'name').'")'; @@ -757,11 +757,11 @@ class NpcBaseResponse extends TemplateResponse implements ICache // tab: objective of quest $conditions = array( - 'OR', - ['AND', ['reqNpcOrGo1', [$this->typeId]], ['reqNpcOrGoCount1', 0, '>']], - ['AND', ['reqNpcOrGo2', [$this->typeId]], ['reqNpcOrGoCount2', 0, '>']], - ['AND', ['reqNpcOrGo3', [$this->typeId]], ['reqNpcOrGoCount3', 0, '>']], - ['AND', ['reqNpcOrGo4', [$this->typeId]], ['reqNpcOrGoCount4', 0, '>']] + DB::OR, + [DB::AND, ['reqNpcOrGo1', [$this->typeId]], ['reqNpcOrGoCount1', 0, '>']], + [DB::AND, ['reqNpcOrGo2', [$this->typeId]], ['reqNpcOrGoCount2', 0, '>']], + [DB::AND, ['reqNpcOrGo3', [$this->typeId]], ['reqNpcOrGoCount3', 0, '>']], + [DB::AND, ['reqNpcOrGo4', [$this->typeId]], ['reqNpcOrGoCount4', 0, '>']] ); foreach ([1, 2] as $i) if (($_ = $this->subject->getField('KillCredit'.$i)) > 0) @@ -782,13 +782,13 @@ class NpcBaseResponse extends TemplateResponse implements ICache // tab: criteria of [ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE have no data set to check for] $conditions = array( - 'AND', + DB::AND, ['ac.type', [ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE]], ['ac.value1', $this->typeId] ); - if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` = ?d AND `value1` = ?d', ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE, $this->typeId)) - $conditions = ['OR', $conditions, ['ac.id', $extraCrt]]; + if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` = %i AND `value1` = %i', ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE, $this->typeId)) + $conditions = [DB::OR, $conditions, ['ac.id', $extraCrt]]; $crtOf = new AchievementList($conditions); if (!$crtOf->error) @@ -803,7 +803,7 @@ class NpcBaseResponse extends TemplateResponse implements ICache } // tab: passengers - if ($_ = DB::World()->selectCol('SELECT `accessory_entry` AS ARRAY_KEY, GROUP_CONCAT(`seat_id` SEPARATOR ", ") FROM vehicle_template_accessory WHERE `entry` = ?d GROUP BY `accessory_entry`', $this->typeId)) + if ($_ = DB::World()->selectCol('SELECT `accessory_entry` AS ARRAY_KEY, GROUP_CONCAT(`seat_id` SEPARATOR ", ") FROM vehicle_template_accessory WHERE `entry` = %i GROUP BY `accessory_entry`', $this->typeId)) { $passengers = new CreatureList(array(['id', array_keys($_)])); if (!$passengers->error) @@ -839,7 +839,7 @@ class NpcBaseResponse extends TemplateResponse implements ICache $this->soundIds = array_merge($this->soundIds, SmartAI::getSoundsPlayedForOwner($this->typeId, SmartAI::SRC_TYPE_CREATURE)); // up to 4 possible displayIds .. for the love of things betwixt, just use the first! - $activitySounds = DB::Aowow()->selectRow('SELECT * FROM ?_creature_sounds WHERE `id` = ?d', $this->subject->getField('displayId1')); + $activitySounds = DB::Aowow()->selectRow('SELECT * FROM ::creature_sounds WHERE `id` = %i', $this->subject->getField('displayId1')); array_shift($activitySounds); // remove id-column $this->soundIds = array_merge($this->soundIds, array_values($activitySounds)); @@ -878,11 +878,11 @@ class NpcBaseResponse extends TemplateResponse implements ICache private function getRepForId(array $entries, array &$spillover) : array { - $rows = DB::World()->select( + $rows = DB::World()->selectAssoc( 'SELECT `creature_id` AS "npc", `RewOnKillRepFaction1` AS "faction", `RewOnKillRepValue1` AS "qty", `MaxStanding1` AS "maxRank", `isTeamAward1` AS "spillover" - FROM creature_onkill_reputation WHERE `creature_id` IN (?a) AND `RewOnKillRepFaction1` > 0 UNION + FROM creature_onkill_reputation WHERE `creature_id` IN %in AND `RewOnKillRepFaction1` > 0 UNION SELECT `creature_id` AS "npc", `RewOnKillRepFaction2` AS "faction", `RewOnKillRepValue2` AS "qty", `MaxStanding2` AS "maxRank", `isTeamAward2` AS "spillover" - FROM creature_onkill_reputation WHERE `creature_id` IN (?a) AND `RewOnKillRepFaction2` > 0', + FROM creature_onkill_reputation WHERE `creature_id` IN %in AND `RewOnKillRepFaction2` > 0', $entries, $entries ); @@ -903,7 +903,7 @@ class NpcBaseResponse extends TemplateResponse implements ICache 0 // spilloverCat ); - $cuRate = DB::World()->selectCell('SELECT `creature_rate` FROM reputation_reward_rate WHERE `creature_rate` <> 1 AND `faction` = ?d', $row['faction']); + $cuRate = DB::World()->selectCell('SELECT `creature_rate` FROM reputation_reward_rate WHERE `creature_rate` <> 1 AND `faction` = %i', $row['faction']); if ($cuRate && User::isInGroup(U_GROUP_EMPLOYEE)) $set[1][1] = $set[1][0] . sprintf(Util::$dfnString, Lang::faction('customRewRate'), ($set[1][0] > 0 ? '+' : '').($set[1][0] * ($cuRate - 1))); else if ($cuRate) diff --git a/endpoints/object/object.php b/endpoints/object/object.php index 9480de5b..60d9281e 100644 --- a/endpoints/object/object.php +++ b/endpoints/object/object.php @@ -68,22 +68,22 @@ class ObjectBaseResponse extends TemplateResponse implements ICache /* Determine Map Type */ /**********************/ - if ($objectdifficulty = DB::Aowow()->select( // has difficulty versions of itself + if ($objectdifficulty = DB::Aowow()->selectAssoc( // has difficulty versions of itself 'SELECT `normal10` AS "0", `normal25` AS "1", `heroic10` AS "2", `heroic25` AS "3", `mapType` AS ARRAY_KEY - FROM ?_objectdifficulty - WHERE `normal10` = ?d OR `normal25` = ?d OR - `heroic10` = ?d OR `heroic25` = ?d', + FROM ::objectdifficulty + WHERE `normal10` = %i OR `normal25` = %i OR + `heroic10` = %i OR `heroic25` = %i', $this->typeId, $this->typeId, $this->typeId, $this->typeId )) { $this->mapType = key($objectdifficulty); $this->difficulties = array_pop($objectdifficulty); } - else if ($maps = DB::Aowow()->selectCell('SELECT IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId` = ?d', Type::OBJECT, $this->typeId)) + else if ($maps = DB::Aowow()->selectCell('SELECT IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ::spawns WHERE `type` = %i AND `typeId` = %i', Type::OBJECT, $this->typeId)) { - $this->mapType = match ((int)DB::Aowow()->selectCell('SELECT `type` FROM ?_zones WHERE `id` = ?d', $maps)) + $this->mapType = match ((int)DB::Aowow()->selectCell('SELECT `type` FROM ::zones WHERE `id` = %i', $maps)) { // MAP_TYPE_DUNGEON, MAP_TYPE_DUNGEON_HC => 1, @@ -102,7 +102,7 @@ class ObjectBaseResponse extends TemplateResponse implements ICache $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // Event (ignore events, where the object only gets removed) - if ($_ = DB::World()->selectCol('SELECT DISTINCT ge.`eventEntry` FROM game_event ge, game_event_gameobject geg, gameobject g WHERE ge.`eventEntry` = geg.`eventEntry` AND g.`guid` = geg.`guid` AND g.`id` = ?d', $this->typeId)) + if ($_ = DB::World()->selectCol('SELECT DISTINCT ge.`eventEntry` FROM game_event ge, game_event_gameobject geg, gameobject g WHERE ge.`eventEntry` = geg.`eventEntry` AND g.`guid` = geg.`guid` AND g.`id` = %i', $this->typeId)) { $this->extendGlobalIds(Type::WORLDEVENT, ...$_); $ev = []; @@ -113,7 +113,7 @@ class ObjectBaseResponse extends TemplateResponse implements ICache } // Faction - if ($_ = DB::Aowow()->selectCell('SELECT `factionId` FROM ?_factiontemplate WHERE `id` = ?d', $this->subject->getField('faction'))) + if ($_ = DB::Aowow()->selectCell('SELECT `factionId` FROM ::factiontemplate WHERE `id` = %i', $this->subject->getField('faction'))) { $this->extendGlobalIds(Type::FACTION, $_); $infobox[] = Util::ucFirst(Lang::game('faction')).Lang::main('colon').'[faction='.$_.']'; @@ -176,7 +176,7 @@ class ObjectBaseResponse extends TemplateResponse implements ICache // SpellFocus if ($_ = $this->subject->getField('spellFocusId')) { - if ($sfo = DB::Aowow()->selectRow('SELECT * FROM ?_spellfocusobject WHERE `id` = ?d', $_)) + if ($sfo = DB::Aowow()->selectRow('SELECT * FROM ::spellfocusobject WHERE `id` = %i', $_)) { $n = Util::localizedString($sfo, 'name'); if (!is_null(GameObjectListFilter::getCriteriaIndex(50, $_))) @@ -242,7 +242,7 @@ class ObjectBaseResponse extends TemplateResponse implements ICache if (User::isInGroup(U_GROUP_EMPLOYEE)) { - $spawnData = DB::Aowow()->select('SELECT `guid` AS "0", `ScriptName` AS "1", `StringId` AS "2" FROM ?_spawns WHERE `type` = ?d AND `typeId` = ?d AND `ScriptName` IS NOT NULL ORDER BY `guid` ASC', Type::OBJECT, $this->typeId); + $spawnData = DB::Aowow()->selectAssoc('SELECT `guid` AS "0", `ScriptName` AS "1", `StringId` AS "2" FROM ::spawns WHERE `type` = %i AND `typeId` = %i AND `ScriptName` IS NOT NULL ORDER BY `guid` ASC', Type::OBJECT, $this->typeId); // AI $scripts = null; @@ -311,16 +311,16 @@ class ObjectBaseResponse extends TemplateResponse implements ICache // todo (low): consider pooled spawns - if ($ll = DB::Aowow()->selectRow('SELECT * FROM ?_loot_link WHERE `objectId` = ?d ORDER BY `priority` DESC LIMIT 1', $this->typeId)) + if ($ll = DB::Aowow()->selectRow('SELECT * FROM ::loot_link WHERE `objectId` = %i ORDER BY `priority` DESC LIMIT 1', $this->typeId)) { // group encounter if ($ll['encounterId']) $this->relBoss = [$ll['npcId'], Lang::profiler('encounterNames', $ll['encounterId'])]; // difficulty dummy - else if ($c = DB::Aowow()->selectRow('SELECT `id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8` FROM ?_creature WHERE `difficultyEntry1` = ?d OR `difficultyEntry2` = ?d OR `difficultyEntry3` = ?d', $ll['npcId'], $ll['npcId'], $ll['npcId'])) + else if ($c = DB::Aowow()->selectRow('SELECT `id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8` FROM ::creature WHERE `difficultyEntry1` = %i OR `difficultyEntry2` = %i OR `difficultyEntry3` = %i', $ll['npcId'], $ll['npcId'], $ll['npcId'])) $this->relBoss = [$c['id'], Util::localizedString($c, 'name')]; // base creature - else if ($c = DB::Aowow()->selectRow('SELECT `id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8` FROM ?_creature WHERE `id` = ?d', $ll['npcId'])) + else if ($c = DB::Aowow()->selectRow('SELECT `id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8` FROM ::creature WHERE `id` = %i', $ll['npcId'])) $this->relBoss = [$c['id'], Util::localizedString($c, 'name')]; } @@ -332,7 +332,7 @@ class ObjectBaseResponse extends TemplateResponse implements ICache if (!$sai->prepare()) // no smartAI found .. check per guid { // at least one of many - $guids = DB::World()->selectCol('SELECT `guid` FROM gameobject WHERE `id` = ?d', $this->typeId); + $guids = DB::World()->selectCol('SELECT `guid` FROM gameobject WHERE `id` = %i', $this->typeId); while ($_ = array_pop($guids)) { $sai = new SmartAI(SmartAI::SRC_TYPE_OBJECT, -$_, ['title' => ' [small](for GUID: '.$_.')[/small]']); @@ -373,10 +373,10 @@ class ObjectBaseResponse extends TemplateResponse implements ICache SPELL_EFFECT_SUMMON_OBJECT_SLOT4 ); $conditions = array( - 'OR', - ['AND', ['effect1Id', $summonEffects], ['effect1MiscValue', $this->typeId]], - ['AND', ['effect2Id', $summonEffects], ['effect2MiscValue', $this->typeId]], - ['AND', ['effect3Id', $summonEffects], ['effect3MiscValue', $this->typeId]] + DB::OR, + [DB::AND, ['effect1Id', $summonEffects], ['effect1MiscValue', $this->typeId]], + [DB::AND, ['effect2Id', $summonEffects], ['effect2MiscValue', $this->typeId]], + [DB::AND, ['effect3Id', $summonEffects], ['effect3MiscValue', $this->typeId]] ); $summons = new SpellList($conditions); @@ -478,15 +478,15 @@ class ObjectBaseResponse extends TemplateResponse implements ICache if ($_ = $this->subject->getField('lootId')) { // check if loot_link entry exists (only difficulty: 1) - if ($npcId = DB::Aowow()->selectCell('SELECT `npcId` FROM ?_loot_link WHERE `objectId` = ?d AND `difficulty` = 1', $this->typeId)) + if ($npcId = DB::Aowow()->selectCell('SELECT `npcId` FROM ::loot_link WHERE `objectId` = %i AND `difficulty` = 1', $this->typeId)) { // get id set of npc $lootEntries = DB::Aowow()->selectCol( 'SELECT ll.`difficulty` AS ARRAY_KEY, o.`lootId` - FROM ?_creature c - LEFT JOIN ?_loot_link ll ON ll.`npcId` IN (c.`id`, c.`difficultyEntry1`, c.`difficultyEntry2`, c.`difficultyEntry3`) - LEFT JOIN ?_objects o ON o.`id` = ll.`objectId` - WHERE c.`id` = ?d + FROM ::creature c + LEFT JOIN ::loot_link ll ON ll.`npcId` IN (c.`id`, c.`difficultyEntry1`, c.`difficultyEntry2`, c.`difficultyEntry3`) + LEFT JOIN ::objects o ON o.`id` = ll.`objectId` + WHERE c.`id` = %i ORDER BY ll.`difficulty` ASC', $npcId ); @@ -579,7 +579,7 @@ class ObjectBaseResponse extends TemplateResponse implements ICache if ($this->difficulties) { $conditions = array( - 'AND', + DB::AND, ['id', $this->difficulties], ['id', $this->typeId, '!'] ); diff --git a/endpoints/pet/pet.php b/endpoints/pet/pet.php index 30da1abd..70064a1d 100644 --- a/endpoints/pet/pet.php +++ b/endpoints/pet/pet.php @@ -116,7 +116,7 @@ class PetBaseResponse extends TemplateResponse implements ICache ['ct.typeFlags', NPC_TYPEFLAG_TAMEABLE, '&'], ['ct.family', $this->typeId], // displayed petType [ - 'OR', // at least neutral to at least one faction + DB::OR, // at least neutral to at least one faction ['ft.A', 1, '<'], ['ft.H', 1, '<'] ] @@ -166,13 +166,13 @@ class PetBaseResponse extends TemplateResponse implements ICache $conditions = [ ['s.typeCat', -3], // Pet-Ability [ - 'OR', + DB::OR, // match: first skillLine ['skillLine1', $this->subject->getField('skillLineId')], // match: second skillLine (if not mask) - ['AND', ['skillLine1', 0, '>'], ['skillLine2OrMask', $this->subject->getField('skillLineId')]], + [DB::AND, ['skillLine1', 0, '>'], ['skillLine2OrMask', $this->subject->getField('skillLineId')]], // match: skillLineMask (if mask) - ['AND', ['skillLine1', -1], ['skillLine2OrMask', $mask, '&']] + [DB::AND, ['skillLine1', -1], ['skillLine2OrMask', $mask, '&']] ] ]; @@ -190,7 +190,7 @@ class PetBaseResponse extends TemplateResponse implements ICache $conditions = array( ['s.typeCat', -7], [ // last rank or unranked - 'OR', + DB::OR, ['s.cuFlags', SPELL_CU_LAST_RANK, '&'], ['s.rankNo', 0] ] diff --git a/endpoints/profile/avatar.php b/endpoints/profile/avatar.php index 34a73734..aa8a9ed2 100644 --- a/endpoints/profile/avatar.php +++ b/endpoints/profile/avatar.php @@ -47,7 +47,7 @@ class ProfileAvatarResponse extends TextResponse $profileId = substr($this->_get['id'], 0, -4); - $charData = DB::Aowow()->selectRow('SELECT `race`, `gender` FROM ?_profiler_profiles WHERE id = ?d', $profileId); + $charData = DB::Aowow()->selectRow('SELECT `race`, `gender` FROM ::profiler_profiles WHERE id = %i', $profileId); if (!$charData) $this->generate404(); diff --git a/endpoints/profile/delete.php b/endpoints/profile/delete.php index 895755dc..ed7572fd 100644 --- a/endpoints/profile/delete.php +++ b/endpoints/profile/delete.php @@ -35,12 +35,12 @@ class ProfileDeleteResponse extends TextResponse return; } + $where = [['`id` IN %in', $this->_get['id']], ['`custom` = 1']]; + if (!User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU)) + $where[] = ['`user` = %i', User::$id]; + // only flag as deleted; only custom profiles - DB::Aowow()->query( - 'UPDATE ?_profiler_profiles SET `deleted` = 1 WHERE `id` IN (?a) AND `custom` = 1 {AND `user` = ?d}', - $this->_get['id'], - User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU) ? DBSIMPLE_SKIP : User::$id - ); + DB::Aowow()->qry('UPDATE ::profiler_profiles SET `deleted` = 1 WHERE %and', $where); } } diff --git a/endpoints/profile/link.php b/endpoints/profile/link.php index 2ba9cea8..ad15f385 100644 --- a/endpoints/profile/link.php +++ b/endpoints/profile/link.php @@ -36,9 +36,9 @@ 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 `custom` = 0', + $newId = DB::Aowow()->qry( + 'REPLACE INTO ::account_profiles (`accountId`, `profileId`, `extraFlags`) + SELECT %i, p.`id`, 0 FROM ::profiler_profiles p WHERE p.`id` = %i AND `custom` = 0', User::$id, $this->_get['id'] ); diff --git a/endpoints/profile/load.php b/endpoints/profile/load.php index 08b996cf..17277037 100644 --- a/endpoints/profile/load.php +++ b/endpoints/profile/load.php @@ -40,7 +40,7 @@ class ProfileLoadResponse extends TextResponse return; } - $pBase = DB::Aowow()->selectRow('SELECT pg.`name` AS "guildname", p.* FROM ?_profiler_profiles p LEFT JOIN ?_profiler_guild pg ON pg.`id` = p.`guild` WHERE p.`id` = ?d', $this->_get['id'][0]); + $pBase = DB::Aowow()->selectRow('SELECT pg.`name` AS "guildname", p.* FROM ::profiler_profiles p LEFT JOIN ::profiler_guild pg ON pg.`id` = p.`guild` WHERE p.`id` = %i', $this->_get['id'][0]); if (!$pBase) { trigger_error('ProfileLoadResponse - called with invalid profileId #'.$this->_get['id'][0], E_USER_WARNING); @@ -111,7 +111,7 @@ class ProfileLoadResponse extends TextResponse $profile['sourcename'] = $pBase['sourceName']; $profile['description'] = $pBase['description']; $profile['user'] = $pBase['user']; - $profile['username'] = DB::Aowow()->selectCell('SELECT `username` FROM ?_account WHERE `id` = ?d', $pBase['user']); + $profile['username'] = DB::Aowow()->selectCell('SELECT `username` FROM ::account WHERE `id` = %i', $pBase['user']); } // custom profiles inherit this when copied from real char :( @@ -123,19 +123,19 @@ class ProfileLoadResponse extends TextResponse } // bookmarks - if ($_ = DB::Aowow()->selectCol('SELECT `accountId` FROM ?_account_profiles WHERE `profileId` = ?d', $pBase['id'])) + if ($_ = DB::Aowow()->selectCol('SELECT `accountId` FROM ::account_profiles WHERE `profileId` = %i', $pBase['id'])) $profile['bookmarks'] = $_; // arena teams - [size(2|3|5) => name]; name gets urlized to use as link - if ($at = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, `name` FROM ?_profiler_arena_team at JOIN ?_profiler_arena_team_member atm ON atm.`arenaTeamId` = at.`id` WHERE atm.`profileId` = ?d', $pBase['id'])) + if ($at = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, `name` FROM ::profiler_arena_team at JOIN ::profiler_arena_team_member atm ON atm.`arenaTeamId` = at.`id` WHERE atm.`profileId` = %i', $pBase['id'])) $profile['arenateams'] = $at; // pets if hunter fields: [name:name, family:petFamily, npc:npcId, displayId:modelId, talents:talentString] - if ($pets = DB::Aowow()->select('SELECT `name`, `family`, `npc`, `displayId`, CONCAT("$\"", `talents`, "\"") AS "talents" FROM ?_profiler_pets WHERE `owner` = ?d', $pBase['id'])) + if ($pets = DB::Aowow()->selectAssoc('SELECT `name`, `family`, `npc`, `displayId`, CONCAT(\'$"\', `talents`, \'"\') AS "talents" FROM ::profiler_pets WHERE `owner` = %i', $pBase['id'])) $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 `deleted` = ?d}', $pBase['id'], User::isInGroup(U_GROUP_STAFF) ? DBSIMPLE_SKIP : 0)) + if ($customs = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `name`, `user`, `icon` FROM ::profiler_profiles WHERE `sourceId` = %i AND `sourceId` <> `id` AND `deleted` IN %in', $pBase['id'], User::isInGroup(U_GROUP_STAFF) ? [0, 1] : [0])) { foreach ($customs as $id => $cu) { @@ -158,7 +158,7 @@ class ProfileLoadResponse extends TextResponse // questId => [cat1, cat2] $profile['quests'] = []; - if ($quests = DB::Aowow()->selectCol('SELECT `questId` FROM ?_profiler_completion_quests WHERE `id` = ?d', $pBase['id'])) + if ($quests = DB::Aowow()->selectCol('SELECT `questId` FROM ::profiler_completion_quests WHERE `id` = %i', $pBase['id'])) { $qList = new QuestList(array(['id', $quests])); if (!$qList->error) @@ -167,28 +167,28 @@ class ProfileLoadResponse extends TextResponse } // skillId => [value, max] - $profile['skills'] = DB::Aowow()->select('SELECT `skillId` AS ARRAY_KEY, `value` AS "0", `max` AS "1" FROM ?_profiler_completion_skills WHERE `id` = ?d', $pBase['id']); + $profile['skills'] = DB::Aowow()->selectAssoc('SELECT `skillId` AS ARRAY_KEY, `value` AS "0", `max` AS "1" FROM ::profiler_completion_skills WHERE `id` = %i', $pBase['id']); // factionId => amount - $profile['reputation'] = DB::Aowow()->selectCol('SELECT `factionId` AS ARRAY_KEY, `standing` FROM ?_profiler_completion_reputation WHERE `id` = ?d', $pBase['id']); + $profile['reputation'] = DB::Aowow()->selectCol('SELECT `factionId` AS ARRAY_KEY, `standing` FROM ::profiler_completion_reputation WHERE `id` = %i', $pBase['id']); // titleId => 1 - $profile['titles'] = DB::Aowow()->selectCol('SELECT `titleId` AS ARRAY_KEY, 1 FROM ?_profiler_completion_titles WHERE `id` = ?d', $pBase['id']); + $profile['titles'] = DB::Aowow()->selectCol('SELECT `titleId` AS ARRAY_KEY, 1 FROM ::profiler_completion_titles WHERE `id` = %i', $pBase['id']); // achievementId => js date object - $profile['achievements'] = DB::Aowow()->selectCol('SELECT `achievementId` AS ARRAY_KEY, CONCAT("$new Date(", `date` * 1000, ")") FROM ?_profiler_completion_achievements WHERE `id` = ?d', $pBase['id']); + $profile['achievements'] = DB::Aowow()->selectCol('SELECT `achievementId` AS ARRAY_KEY, CONCAT("$new Date(", `date` * 1000, ")") FROM ::profiler_completion_achievements WHERE `id` = %i', $pBase['id']); // just points - $profile['achievementpoints'] = $profile['achievements'] ? DB::Aowow()->selectCell('SELECT SUM(`points`) FROM ?_achievement WHERE `id` IN (?a)', array_keys($profile['achievements'])) : 0; + $profile['achievementpoints'] = $profile['achievements'] ? DB::Aowow()->selectCell('SELECT SUM(`points`) FROM ::achievement WHERE `id` IN %in', array_keys($profile['achievements'])) : 0; // achievementId => counter - $profile['statistics'] = DB::Aowow()->selectCol('SELECT `achievementId` AS ARRAY_KEY, `counter` FROM ?_profiler_completion_statistics WHERE `id` = ?d', $pBase['id']); + $profile['statistics'] = DB::Aowow()->selectCol('SELECT `achievementId` AS ARRAY_KEY, `counter` FROM ::profiler_completion_statistics WHERE `id` = %i', $pBase['id']); // achievementId => 1 - $profile['activity'] = DB::Aowow()->selectCol('SELECT `achievementId` AS ARRAY_KEY, 1 FROM ?_profiler_completion_statistics WHERE `id` = ?d AND `date` > ?d', $pBase['id'], time() - MONTH); + $profile['activity'] = DB::Aowow()->selectCol('SELECT `achievementId` AS ARRAY_KEY, 1 FROM ::profiler_completion_statistics WHERE `id` = %i AND `date` > %i', $pBase['id'], time() - MONTH); // spellId => 1 - $profile['spells'] = DB::Aowow()->selectCol('SELECT `spellId` AS ARRAY_KEY, 1 FROM ?_profiler_completion_spells WHERE `id` = ?d', $pBase['id']); + $profile['spells'] = DB::Aowow()->selectCol('SELECT `spellId` AS ARRAY_KEY, 1 FROM ::profiler_completion_spells WHERE `id` = %i', $pBase['id']); $gItems = []; @@ -224,7 +224,7 @@ class ProfileLoadResponse extends TextResponse } } - if ($items = DB::Aowow()->select('SELECT * FROM ?_profiler_items WHERE `id` = ?d', $pBase['id'])) + if ($items = DB::Aowow()->selectAssoc('SELECT * FROM ::profiler_items WHERE `id` = %i', $pBase['id'])) { $itemz = new ItemList(array(['id', array_column($items, 'item')])); if (!$itemz->error) diff --git a/endpoints/profile/pin.php b/endpoints/profile/pin.php index d8da5418..9b871a44 100644 --- a/endpoints/profile/pin.php +++ b/endpoints/profile/pin.php @@ -40,7 +40,7 @@ class ProfilePinResponse extends TextResponse if (!$this->_get['user'] || User::$username == $this->_get['user']) $uid = User::$id; else if ($this->_get['user'] && User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU)) - $uid = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user']); + $uid = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user']); if (!$uid) { @@ -49,9 +49,9 @@ class ProfilePinResponse extends TextResponse } // since only one character can be pinned at a time we can reset everything - DB::Aowow()->query('UPDATE ?_account_profiles SET `extraFlags` = `extraFlags` & ~?d WHERE `accountId` = ?d', PROFILER_CU_PINNED, $uid); + DB::Aowow()->qry('UPDATE ::account_profiles SET `extraFlags` = `extraFlags` & ~%i WHERE `accountId` = %i', PROFILER_CU_PINNED, $uid); // and set a single char if necessary (Replace, because this entry may not exist yet) - DB::Aowow()->query('REPLACE INTO ?_account_profiles (`accountId`, `profileId`, `extraFlags`) VALUES (?d, ?d, ?d)', $uid, $this->_get['id'][0], PROFILER_CU_PINNED); + DB::Aowow()->qry('REPLACE INTO ::account_profiles (`accountId`, `profileId`, `extraFlags`) VALUES (%i, %i, %i)', $uid, $this->_get['id'][0], PROFILER_CU_PINNED); } } diff --git a/endpoints/profile/private.php b/endpoints/profile/private.php index 1e8433fa..c42a50c2 100644 --- a/endpoints/profile/private.php +++ b/endpoints/profile/private.php @@ -48,7 +48,7 @@ class ProfilePrivateResponse extends TextResponse if (!$this->_get['user'] || User::$username == $this->_get['user']) $uid = User::$id; else if ($this->_get['user'] && User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU)) - $uid = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user']); + $uid = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user']); if (!$uid) { @@ -56,8 +56,8 @@ class ProfilePrivateResponse extends TextResponse return; } - DB::Aowow()->query('UPDATE ?_account_profiles SET `extraFlags` = `extraFlags` & ~?d WHERE `profileId` IN (?a) AND `accountId` = ?d', PROFILER_CU_PUBLISHED, $this->_get['id'], $uid); - DB::Aowow()->query('UPDATE ?_profiler_profiles SET `cuFlags` = `cuFlags` & ~?d WHERE `id` IN (?a) AND `user` = ?d', PROFILER_CU_PUBLISHED, $this->_get['id'], $uid); + DB::Aowow()->qry('UPDATE ::account_profiles SET `extraFlags` = `extraFlags` & ~%i WHERE `profileId` IN %in AND `accountId` = %i', PROFILER_CU_PUBLISHED, $this->_get['id'], $uid); + DB::Aowow()->qry('UPDATE ::profiler_profiles SET `cuFlags` = `cuFlags` & ~%i WHERE `id` IN %in AND `user` = %i', PROFILER_CU_PUBLISHED, $this->_get['id'], $uid); } } diff --git a/endpoints/profile/profile.php b/endpoints/profile/profile.php index 3636624f..53a7f8be 100644 --- a/endpoints/profile/profile.php +++ b/endpoints/profile/profile.php @@ -67,7 +67,7 @@ class ProfileBaseResponse extends TemplateResponse // 3 possibilities // 1) already synced to aowow - 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)) + if ($subject = DB::Aowow()->selectRow('SELECT `id`, `realmGUID`, `stub` FROM ::profiler_profiles WHERE `realm` = %i AND `custom` = 0 AND `name` = %s AND `renameItr` = %i', $this->realmId, Util::ucFirst($this->subjectName), $rnItr)) { $this->typeId = $subject['id']; @@ -82,36 +82,35 @@ class ProfileBaseResponse extends TemplateResponse $this->notFound(); // 2) not yet synced but exists on realm (and not a gm character) - $subjects = DB::Characters($this->realmId)->select( + $subjects = DB::Characters($this->realmId)->selectAssoc( 'SELECT c.`guid` AS "realmGUID", c.`name`, c.`race`, c.`class`, c.`level`, c.`gender`, c.`at_login`, g.`guildid` AS "guildGUID", IFNULL(g.`name`, "") AS "guildName", IFNULL(gm.`rank`, 0) AS "guildRank" FROM characters c LEFT JOIN guild_member gm ON gm.`guid` = c.`guid` LEFT JOIN guild g ON g.`guildid` = gm.`guildid` - WHERE c.`name` = ? AND `level` <= ?d AND (`extra_flags` & ?d) = 0', + WHERE c.`name` = %s AND `level` <= %i AND (`extra_flags` & %i) = 0', Util::ucFirst($this->subjectName), MAX_LEVEL, Profiler::CHAR_GMFLAGS ); - if ($subject = array_filter($subjects ?: [], fn($x) => Util::lower($x['name']) == Util::lower($this->subjectName))) + if ($subject = array_find($subjects ?: [], fn($x) => Util::lower($x['name']) == Util::lower($this->subjectName))) { - $subject = $subject[0]; $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 `custom` = 0 AND `name` = ?', $this->realmId, $subject['name']); + $subject['renameItr'] = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ::profiler_profiles WHERE `realm` = %i AND `custom` = 0 AND `name` = %s', $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']); + $subject['guild'] = DB::Aowow()->selectCell('SELECT `id` FROM ::profiler_guild WHERE `realm` = %i AND `realmGUID` = %i', $this->realmId, $subject['guildGUID']); if (!$subject['guild']) - $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'])); + $subject['guild'] = DB::Aowow()->qry('INSERT INTO ::profiler_guild (`realm`, `realmGUID`, `stub`, `name`, `nameUrl`) VALUES (%i, %i, 1, %s, %s)', $this->realmId, $subject['guildGUID'], $subject['guildName'], Profiler::urlize($subject['guildName'])); } unset($subject['guildGUID'], $subject['guildName'], $subject['at_login']); // create entry from realm with enough basic info to disply tooltips - DB::Aowow()->query('REPLACE INTO ?_profiler_profiles (?#) VALUES (?a)', array_keys($subject), array_values($subject)); - $this->typeId = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` = ?d', $this->realmId, $subject['realmGUID']); + DB::Aowow()->qry('REPLACE INTO ::profiler_profiles %v', $subject); + $this->typeId = DB::Aowow()->selectCell('SELECT `id` FROM ::profiler_profiles WHERE `realm` = %i AND `realmGUID` = %i', $this->realmId, $subject['realmGUID']); $this->handleIncompleteData(Type::PROFILE, $subject['realmGUID']); return; diff --git a/endpoints/profile/profile_power.php b/endpoints/profile/profile_power.php index 4d5b632b..cbc0d0e6 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 `custom` = 0 AND `name` = ? AND `renameItr` = ?d', $this->realmId, Util::ucWords($this->subjectName), $renameItr ?? 0)) + if ($x = DB::Aowow()->selectCell('SELECT `id` FROM ::profiler_profiles WHERE `realm` = %i AND `custom` = 0 AND `name` = %s AND `renameItr` = %i', $this->realmId, Util::ucWords($this->subjectName), $renameItr ?? 0)) $this->typeId = $x; } diff --git a/endpoints/profile/public.php b/endpoints/profile/public.php index 9193d426..98f70eae 100644 --- a/endpoints/profile/public.php +++ b/endpoints/profile/public.php @@ -48,7 +48,7 @@ class ProfilePublicResponse extends TextResponse if (!$this->_get['user'] || User::$username == $this->_get['user']) $uid = User::$id; else if ($this->_get['user'] && User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU)) - $uid = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user']); + $uid = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user']); if (!$uid) { @@ -56,8 +56,8 @@ class ProfilePublicResponse extends TextResponse return; } - DB::Aowow()->query('UPDATE ?_account_profiles SET `extraFlags` = `extraFlags` | ?d WHERE `profileId` IN (?a) AND `accountId` = ?d', PROFILER_CU_PUBLISHED, $this->_get['id'], $uid); - DB::Aowow()->query('UPDATE ?_profiler_profiles SET `cuFlags` = `cuFlags` | ?d WHERE `id` IN (?a) AND `user` = ?d', PROFILER_CU_PUBLISHED, $this->_get['id'], $uid); + DB::Aowow()->qry('UPDATE ::account_profiles SET `extraFlags` = `extraFlags` | %i WHERE `profileId` IN %in AND `accountId` = %i', PROFILER_CU_PUBLISHED, $this->_get['id'], $uid); + DB::Aowow()->qry('UPDATE ::profiler_profiles SET `cuFlags` = `cuFlags` | %i WHERE `id` IN %in AND `user` = %i', PROFILER_CU_PUBLISHED, $this->_get['id'], $uid); } } diff --git a/endpoints/profile/resync.php b/endpoints/profile/resync.php index 29ef263a..0b93276a 100644 --- a/endpoints/profile/resync.php +++ b/endpoints/profile/resync.php @@ -27,7 +27,7 @@ class ProfileResyncResponse extends TextResponse */ protected function generate() : void { - if ($chars = DB::Aowow()->select('SELECT `realm`, `realmGUID` FROM ?_profiler_profiles WHERE `id` IN (?a)', $this->_get['id'])) + if ($chars = DB::Aowow()->selectAssoc('SELECT `realm`, `realmGUID` FROM ::profiler_profiles WHERE `id` IN %in', $this->_get['id'])) { foreach ($chars as $c) Profiler::scheduleResync(Type::PROFILE, $c['realm'], $c['realmGUID']); diff --git a/endpoints/profile/save.php b/endpoints/profile/save.php index cf57e651..70a4e9f7 100644 --- a/endpoints/profile/save.php +++ b/endpoints/profile/save.php @@ -89,26 +89,26 @@ 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 `custom` = 0', $_)) + if ($r = DB::Aowow()->selectCell('SELECT `realm` FROM ::profiler_profiles WHERE `id` = %i AND `custom` = 0', $_)) $cuProfile['realm'] = $r; $cuProfile['sourceId'] = $_; } if (!empty($cuProfile['sourceId'])) - $cuProfile['sourceName'] = DB::Aowow()->selectCell('SELECT `name` FROM ?_profiler_profiles WHERE `id` = ?d', $cuProfile['sourceId']); + $cuProfile['sourceName'] = DB::Aowow()->selectCell('SELECT `name` FROM ::profiler_profiles WHERE `id` = %i', $cuProfile['sourceId']); $charId = -1; if ($id = $this->_get['id'][0]) // update { - if ($charId = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_profiles WHERE `id` = ?d', $id)) - DB::Aowow()->query('UPDATE ?_profiler_profiles SET ?a WHERE `id` = ?d', $cuProfile, $id); + if ($charId = DB::Aowow()->selectCell('SELECT `id` FROM ::profiler_profiles WHERE `id` = %i', $id)) + DB::Aowow()->qry('UPDATE ::profiler_profiles SET %a WHERE `id` = %i', $cuProfile, $id); } else // new { - $nProfiles = DB::Aowow()->selectCell('SELECT COUNT(*) FROM ?_profiler_profiles WHERE `user` = ?d AND `deleted` = 0 AND `custom` = 1', User::$id); + $nProfiles = DB::Aowow()->selectCell('SELECT COUNT(*) FROM ::profiler_profiles WHERE `user` = %i 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))) + if ($newId = DB::Aowow()->qry('INSERT INTO ::profiler_profiles %v', $cuProfile)) $charId = $newId; } @@ -148,7 +148,7 @@ class ProfileSaveResponse extends TextResponse if ($slot + 1 == array_sum($itemData)) // only slot definition set => empty slot { - DB::Aowow()->query('DELETE FROM ?_profiler_items WHERE `id` = ?d AND `slot` = ?d', $charId, $itemData[0]); + DB::Aowow()->qry('DELETE FROM ::profiler_items WHERE `id` = %i AND `slot` = %i', $charId, $itemData[0]); continue; } @@ -176,7 +176,7 @@ class ProfileSaveResponse extends TextResponse // looks good array_unshift($itemData, $charId); - DB::Aowow()->query('REPLACE INTO ?_profiler_items (?#) VALUES (?a)', $keys, $itemData); + DB::Aowow()->qry('REPLACE INTO ::profiler_items %v', array_combine($keys, $itemData)); } } } diff --git a/endpoints/profile/status.php b/endpoints/profile/status.php index 117a50e3..ac086f84 100644 --- a/endpoints/profile/status.php +++ b/endpoints/profile/status.php @@ -31,9 +31,9 @@ class ProfileStatusResponse extends TextResponse { // roster resync for this guild was requested -> get char list if ($this->_get['guild']) - $ids = DB::Aowow()->selectCol('SELECT `id` FROM ?_profiler_profiles WHERE `guild` IN (?a)', $this->_get['id']); + $ids = DB::Aowow()->selectCol('SELECT `id` FROM ::profiler_profiles WHERE `guild` IN %in', $this->_get['id']); else if ($this->_get['arena-team']) - $ids = DB::Aowow()->selectCol('SELECT `profileId` FROM ?_profiler_arena_team_member WHERE `arenaTeamId` IN (?a)', $this->_get['id']); + $ids = DB::Aowow()->selectCol('SELECT `profileId` FROM ::profiler_arena_team_member WHERE `arenaTeamId` IN %in', $this->_get['id']); else $ids = $this->_get['id']; diff --git a/endpoints/profile/unlink.php b/endpoints/profile/unlink.php index 28aad3a9..322521e3 100644 --- a/endpoints/profile/unlink.php +++ b/endpoints/profile/unlink.php @@ -47,7 +47,7 @@ class ProfileUnlinkResponse extends TextResponse if (!$this->_get['user'] || User::$username == $this->_get['user']) $uid = User::$id; else if ($this->_get['user'] && User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU)) - $uid = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user']); + $uid = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user']); if (!$uid) { @@ -55,7 +55,7 @@ class ProfileUnlinkResponse extends TextResponse return; } - DB::Aowow()->query('DELETE FROM ?_account_profiles WHERE `accountId` = ?d AND `profileId` IN (?a)', $uid, $this->_get['id']); + DB::Aowow()->qry('DELETE FROM ::account_profiles WHERE `accountId` = %i AND `profileId` IN %in', $uid, $this->_get['id']); } } diff --git a/endpoints/profile/unpin.php b/endpoints/profile/unpin.php index fdb7ad90..dceb00f8 100644 --- a/endpoints/profile/unpin.php +++ b/endpoints/profile/unpin.php @@ -40,7 +40,7 @@ class ProfileUnpinResponse extends TextResponse if (!$this->_get['user'] || User::$username == $this->_get['user']) $uid = User::$id; else if ($this->_get['user'] && User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU)) - $uid = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $this->_get['user']); + $uid = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $this->_get['user']); if (!$uid) { @@ -48,7 +48,7 @@ class ProfileUnpinResponse extends TextResponse return; } - DB::Aowow()->query('UPDATE ?_account_profiles SET `extraFlags` = `extraFlags` & ~?d WHERE `accountId` = ?d', PROFILER_CU_PINNED, $uid); + DB::Aowow()->qry('UPDATE ::account_profiles SET `extraFlags` = `extraFlags` & ~%i WHERE `accountId` = %i', PROFILER_CU_PINNED, $uid); } } diff --git a/endpoints/profiles/profiles.php b/endpoints/profiles/profiles.php index 3b3ab0af..8821cb0c 100644 --- a/endpoints/profiles/profiles.php +++ b/endpoints/profiles/profiles.php @@ -51,7 +51,7 @@ class ProfilesBaseResponse extends TemplateResponse implements IProfilerList if ($this->realm && $r['name'] != $this->realm) continue; - $this->sumSubjects += DB::Characters($idx)->selectCell('SELECT COUNT(*) FROM characters WHERE `deleteInfos_Name` IS NULL AND `level` <= ?d AND (`extra_flags` & ?) = 0', MAX_LEVEL, Profiler::CHAR_GMFLAGS); + $this->sumSubjects += DB::Characters($idx)->selectCell('SELECT COUNT(*) FROM characters WHERE `deleteInfos_Name` IS NULL AND `level` <= %i AND (`extra_flags` & ?) = 0', MAX_LEVEL, Profiler::CHAR_GMFLAGS); $realms[] = $idx; } diff --git a/endpoints/quest/quest.php b/endpoints/quest/quest.php index 38fad38b..815e5777 100644 --- a/endpoints/quest/quest.php +++ b/endpoints/quest/quest.php @@ -200,7 +200,7 @@ class QuestBaseResponse extends TemplateResponse implements ICache if ($_ = $this->subject->getField('timeLimit')) $infobox[] = Lang::quest('timer').DateTime::formatTimeElapsedFloat($_ * 1000); - $startEnd = DB::Aowow()->select('SELECT * FROM ?_quests_startend WHERE `questId` = ?d', $this->typeId); + $startEnd = DB::Aowow()->selectAssoc('SELECT * FROM ::quests_startend WHERE `questId` = %i', $this->typeId); // start $start = '[icon name=quest_start'.($this->subject->isRepeatable() ? '_daily' : '').']'.Lang::event('start').'[/icon]'; @@ -279,8 +279,8 @@ class QuestBaseResponse extends TemplateResponse implements ICache // profiler relateed (note that this is part of the cache. I don't think this is important enough to calc for every view) 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 `custom` = 0 AND `stub` = 0'); + $x = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ::profiler_completion_quests WHERE `questId` = %i', $this->typeId); + $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 @@ -384,7 +384,7 @@ class QuestBaseResponse extends TemplateResponse implements ICache // .. creature kills if ($ids = array_keys($olNPCs)) { - $olNPCData = new CreatureList(array('OR', ['id', $ids], ['killCredit1', $ids], ['killCredit2', $ids])); + $olNPCData = new CreatureList(array(DB::OR, ['id', $ids], ['killCredit1', $ids], ['killCredit2', $ids])); $this->extendGlobalData($olNPCData->getJSGlobals(GLOBALINFO_SELF)); // create proxy-references @@ -572,9 +572,9 @@ class QuestBaseResponse extends TemplateResponse implements ICache // dear god, if you are one of the types who puts queststarter-items in container-items, in conatiner-items, in container-items, in container-GOs .. you should kill yourself by killing yourself! // so yeah .. no recursion checking $vendors = DB::World()->selectCol( - 'SELECT nv.`entry` FROM npc_vendor nv WHERE nv.`item` = ?d UNION - SELECT nv1.`entry` FROM npc_vendor nv1 JOIN npc_vendor nv2 ON -nv1.`item` = nv2.`entry` WHERE nv2.`item` = ?d UNION - SELECT c.`id` FROM game_event_npc_vendor genv JOIN creature c ON c.`guid` = genv.`guid` WHERE genv.`item` = ?d', + 'SELECT nv.`entry` FROM npc_vendor nv WHERE nv.`item` = %i UNION + SELECT nv1.`entry` FROM npc_vendor nv1 JOIN npc_vendor nv2 ON -nv1.`item` = nv2.`entry` WHERE nv2.`item` = %i UNION + SELECT c.`id` FROM game_event_npc_vendor genv JOIN creature c ON c.`guid` = genv.`guid` WHERE genv.`item` = %i', $itemId, $itemId, $itemId ); foreach ($vendors as $v) @@ -638,9 +638,9 @@ class QuestBaseResponse extends TemplateResponse implements ICache if ($_specialFlags & QUEST_FLAG_SPECIAL_EXT_COMPLETE) { // areatrigger - if ($atir = DB::Aowow()->selectCol('SELECT `id` FROM ?_areatrigger WHERE `type` = ?d AND `quest` = ?d', AT_TYPE_OBJECTIVE, $this->typeId)) + if ($atir = DB::Aowow()->selectCol('SELECT `id` FROM ::areatrigger WHERE `type` = %i AND `quest` = %i', AT_TYPE_OBJECTIVE, $this->typeId)) { - if ($atSpawns = DB::AoWoW()->select('SELECT `typeId` AS ARRAY_KEY, `posX`, `posY`, `floor`, `areaId` FROM ?_spawns WHERE `type` = ?d AND `typeId` IN (?a)', Type::AREATRIGGER, $atir)) + if ($atSpawns = DB::AoWoW()->selectAssoc('SELECT `typeId` AS ARRAY_KEY, `posX`, `posY`, `floor`, `areaId` FROM ::spawns WHERE `type` = %i AND `typeId` IN %in', Type::AREATRIGGER, $atir)) { if (User::isInGroup(U_GROUP_STAFF)) $endTextWrapper = '<a href="?areatrigger='.$atir[0].'">%s</a>'; @@ -672,7 +672,7 @@ class QuestBaseResponse extends TemplateResponse implements ICache } } // complete-spell - else if ($endSpell = new SpellList(array('OR', ['AND', ['effect1Id', SPELL_EFFECT_QUEST_COMPLETE], ['effect1MiscValue', $this->typeId]], ['AND', ['effect2Id', SPELL_EFFECT_QUEST_COMPLETE], ['effect2MiscValue', $this->typeId]], ['AND', ['effect3Id', SPELL_EFFECT_QUEST_COMPLETE], ['effect3MiscValue', $this->typeId]]))) + else if ($endSpell = new SpellList(array(DB::OR, [DB::AND, ['effect1Id', SPELL_EFFECT_QUEST_COMPLETE], ['effect1MiscValue', $this->typeId]], [DB::AND, ['effect2Id', SPELL_EFFECT_QUEST_COMPLETE], ['effect2MiscValue', $this->typeId]], [DB::AND, ['effect3Id', SPELL_EFFECT_QUEST_COMPLETE], ['effect3MiscValue', $this->typeId]]))) if (!$endSpell->error) $endTextWrapper = '<a href="?spell='.$endSpell->id.'">%s</a>'; } @@ -916,7 +916,7 @@ class QuestBaseResponse extends TemplateResponse implements ICache $this->addScript([SC_CSS_FILE, 'css/Book.css']); // factionchange-equivalent - if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = ?d, `alliance_id`, -`horde_id`) FROM player_factionchange_quests WHERE `alliance_id` = ?d OR `horde_id` = ?d', $this->typeId, $this->typeId, $this->typeId)) + if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = %i, `alliance_id`, -`horde_id`) FROM player_factionchange_quests WHERE `alliance_id` = %i OR `horde_id` = %i', $this->typeId, $this->typeId, $this->typeId)) { $altQuest = new QuestList(array(['id', abs($pendant)])); if (!$altQuest->error) @@ -962,9 +962,9 @@ class QuestBaseResponse extends TemplateResponse implements ICache } // tab: spawning pool (for the swarm) - if ($qp = DB::World()->selectCol('SELECT qpm2.`questId` FROM quest_pool_members qpm1 JOIN quest_pool_members qpm2 ON qpm1.`poolId` = qpm2.`poolId` WHERE qpm1.`questId` = ?d', $this->typeId)) + if ($qp = DB::World()->selectCol('SELECT qpm2.`questId` FROM quest_pool_members qpm1 JOIN quest_pool_members qpm2 ON qpm1.`poolId` = qpm2.`poolId` WHERE qpm1.`questId` = %i', $this->typeId)) { - $max = DB::World()->selectCell('SELECT `numActive` FROM quest_pool_template qpt JOIN quest_pool_members qpm ON qpm.`poolId` = qpt.`poolId` WHERE qpm.`questId` = ?d', $this->typeId); + $max = DB::World()->selectCell('SELECT `numActive` FROM quest_pool_template qpt JOIN quest_pool_members qpm ON qpm.`poolId` = qpt.`poolId` WHERE qpm.`questId` = %i', $this->typeId); $pooledQuests = new QuestList(array(['id', $qp])); if (!$pooledQuests->error) { @@ -1169,7 +1169,7 @@ class QuestBaseResponse extends TemplateResponse implements ICache return false; $delay = $this->subject->getField('rewardMailDelay'); - $letter = DB::Aowow()->selectRow('SELECT * FROM ?_mails WHERE `id` = ?d', $rmtId); + $letter = DB::Aowow()->selectRow('SELECT * FROM ::mails WHERE `id` = %i', $rmtId); $this->mail = array( 'attachments' => [], @@ -1183,7 +1183,7 @@ class QuestBaseResponse extends TemplateResponse implements ICache ); $senderTypeId = 0; - if ($_= DB::World()->selectCell('SELECT `RewardMailSenderEntry` FROM quest_mail_sender WHERE `QuestId` = ?d', $this->typeId)) + if ($_= DB::World()->selectCell('SELECT `RewardMailSenderEntry` FROM quest_mail_sender WHERE `QuestId` = %i', $this->typeId)) $senderTypeId = $_; else foreach ($startEnd as $se) @@ -1242,7 +1242,7 @@ class QuestBaseResponse extends TemplateResponse implements ICache 'name' => FactionList::getName($fac) ); - if ($cuRates = DB::World()->selectRow('SELECT * FROM reputation_reward_rate WHERE `faction` = ?d', $fac)) + if ($cuRates = DB::World()->selectRow('SELECT * FROM reputation_reward_rate WHERE `faction` = %i', $fac)) { if ($this->subject->isRepeatable()) $rep['qty'][1] = $rep['qty'][0] * ($cuRates['quest_repeatable_rate'] - 1); @@ -1290,15 +1290,15 @@ class QuestBaseResponse extends TemplateResponse implements ICache // so we fast forward to the last quest and go backwards from there. $lastQuestId = $this->subject->getField('nextQuestIdChain'); - while ($newLast = DB::Aowow()->selectCell('SELECT `nextQuestIdChain` FROM ?_quests WHERE `id` = ?d AND `id` <> `nextQuestIdChain`', $lastQuestId)) + while ($newLast = DB::Aowow()->selectCell('SELECT `nextQuestIdChain` FROM ::quests WHERE `id` = %i AND `id` <> `nextQuestIdChain`', $lastQuestId)) $lastQuestId = $newLast; - $end = DB::Aowow()->selectRow('SELECT `id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `reqRaceMask` FROM ?_quests WHERE `id` = ?d', $lastQuestId ?: $this->typeId); + $end = DB::Aowow()->selectRow('SELECT `id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `reqRaceMask` FROM ::quests WHERE `id` = %i', $lastQuestId ?: $this->typeId); $chain = array(array($makeSeriesItem($end))); // series / step / quest $prevStepIds = [$lastQuestId ?: $this->typeId]; - while ($prevQuests = DB::Aowow()->select('SELECT `id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `reqRaceMask` FROM ?_quests WHERE `nextQuestIdChain` IN (?a) AND `id` <> `nextQuestIdChain`{ AND (`cuFlags` & ?d) = 0}', - $prevStepIds, User::isInGroup(U_GROUP_STAFF) ? CUSTOM_EXCLUDE_FOR_LISTVIEW : DBSIMPLE_SKIP)) + while ($prevQuests = DB::Aowow()->selectAssoc('SELECT `id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `reqRaceMask` FROM ::quests WHERE `nextQuestIdChain` IN %in AND `id` <> `nextQuestIdChain` AND (`cuFlags` & %i) = 0', + $prevStepIds, User::isInGroup(U_GROUP_STAFF) ? CUSTOM_EXCLUDE_FOR_LISTVIEW : 0)) { $step = []; foreach ($prevQuests as $pQuest) @@ -1327,13 +1327,13 @@ class QuestBaseResponse extends TemplateResponse implements ICache $extraLists = array( // Requires all of these quests (Quests that you must follow to get this quest) - ['reqQ', array('OR', ['AND', ['nextQuestId', $this->typeId], ['exclusiveGroup', 0, '<']], ['AND', ['id', $this->subject->getField('prevQuestId')], ['nextQuestIdChain', $this->typeId, '!']])], + ['reqQ', array(DB::OR, [DB::AND, ['nextQuestId', $this->typeId], ['exclusiveGroup', 0, '<']], [DB::AND, ['id', $this->subject->getField('prevQuestId')], ['nextQuestIdChain', $this->typeId, '!']])], // Requires one of these quests (Requires one of the quests to choose from) - ['reqOneQ', array('OR', ['AND', ['exclusiveGroup', 0, '>='], ['nextQuestId', $this->typeId]], ['breadCrumbForQuestId', $this->typeId])], + ['reqOneQ', array(DB::OR, [DB::AND, ['exclusiveGroup', 0, '>='], ['nextQuestId', $this->typeId]], ['breadCrumbForQuestId', $this->typeId])], // Opens Quests (Quests that become available only after complete this quest (optionally only one)) - ['opensQ', array('OR', ['AND', ['prevQuestId', $this->typeId], ['id', $this->subject->getField('nextQuestIdChain'), '!']], ['id', $this->subject->getField('nextQuestId')], ['id', $this->subject->getField('breadcrumbForQuestId')])], + ['opensQ', array(DB::OR, [DB::AND, ['prevQuestId', $this->typeId], ['id', $this->subject->getField('nextQuestIdChain'), '!']], ['id', $this->subject->getField('nextQuestId')], ['id', $this->subject->getField('breadcrumbForQuestId')])], // Closes Quests (Quests that become inaccessible after completing this quest) ['closesQ', array(['exclusiveGroup', 0, '>'], ['exclusiveGroup', $this->subject->getField('exclusiveGroup')], ['id', $this->typeId, '!'])], diff --git a/endpoints/race/race.php b/endpoints/race/race.php index 866409fd..e331f1b0 100644 --- a/endpoints/race/race.php +++ b/endpoints/race/race.php @@ -218,7 +218,7 @@ class RaceBaseResponse extends TemplateResponse implements ICache // ok, this sucks, but i rather hardcode the trainer, than fetch items by namepart if (isset(self::MOUNT_VENDORS[$this->typeId])) { - if ($items = DB::World()->selectCol('SELECT `item` FROM npc_vendor WHERE `entry` IN (?a)', self::MOUNT_VENDORS[$this->typeId])) + if ($items = DB::World()->selectCol('SELECT `item` FROM npc_vendor WHERE `entry` IN %in', self::MOUNT_VENDORS[$this->typeId])) { $conditions = array( ['i.id', $items], @@ -241,7 +241,7 @@ class RaceBaseResponse extends TemplateResponse implements ICache } // tab: sounds - if ($vo = DB::Aowow()->selectCol('SELECT `soundId` AS ARRAY_KEY, `gender` FROM ?_races_sounds WHERE `raceId` = ?d', $this->typeId)) + if ($vo = DB::Aowow()->selectCol('SELECT `soundId` AS ARRAY_KEY, `gender` FROM ::races_sounds WHERE `raceId` = %i', $this->typeId)) { $sounds = new SoundList(array(['id', array_keys($vo)])); if (!$sounds->error) @@ -260,13 +260,13 @@ class RaceBaseResponse extends TemplateResponse implements ICache // tab: criteria-of $conditions = array( - 'AND', + DB::AND, ['ac.type', ACHIEVEMENT_CRITERIA_TYPE_HK_RACE], ['ac.value1', $this->typeId] ); - if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` IN (?a) AND `value2` = ?d', [ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE, ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE], $this->typeId)) - $conditions = ['OR', $conditions, ['ac.id', $extraCrt]]; + if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` IN %in AND `value2` = %i', [ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE, ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE], $this->typeId)) + $conditions = [DB::OR, $conditions, ['ac.id', $extraCrt]]; $crtOf = new AchievementList($conditions); if (!$crtOf->error) diff --git a/endpoints/reputation/reputation.php b/endpoints/reputation/reputation.php index b47bc33a..0e160637 100644 --- a/endpoints/reputation/reputation.php +++ b/endpoints/reputation/reputation.php @@ -29,7 +29,7 @@ class ReputationBaseResponse extends TemplateResponse array_unshift($this->title, $this->h1); - if ($repData = DB::Aowow()->select('SELECT `action`, `amount`, `date` AS "when", IF(`action` IN (?a), `sourceA`, 0) AS "param" FROM ?_account_reputation WHERE `userId` = ?d', + if ($repData = DB::Aowow()->selectAssoc('SELECT `action`, `amount`, `date` AS "when", IF(`action` IN %in, `sourceA`, 0) AS "param" FROM ::account_reputation WHERE `userId` = %i', [SITEREP_ACTION_COMMENT, SITEREP_ACTION_UPVOTED, SITEREP_ACTION_DOWNVOTED], User::$id)) { array_walk($repData, fn(&$x) => $x['when'] = date(Util::$dateFormatInternal, $x['when'])); diff --git a/endpoints/screenshot/complete.php b/endpoints/screenshot/complete.php index da331f67..5bf80622 100644 --- a/endpoints/screenshot/complete.php +++ b/endpoints/screenshot/complete.php @@ -77,8 +77,8 @@ class ScreenshotCompleteResponse extends TextResponse ['oWidth' => $w, 'oHeight' => $h] = ScreenshotMgr::calcImgDimensions(); // write to db - $newId = DB::Aowow()->query( - 'INSERT INTO ?_screenshots (`type`, `typeId`, `userIdOwner`, `date`, `width`, `height`, `caption`, `status`) VALUES (?d, ?d, ?d, UNIX_TIMESTAMP(), ?d, ?d, ?, 0)', + $newId = DB::Aowow()->qry( + 'INSERT INTO ::screenshots (`type`, `typeId`, `userIdOwner`, `date`, `width`, `height`, `caption`, `status`) VALUES (%i, %i, %i, UNIX_TIMESTAMP(), %i, %i, %s, 0)', $this->destType, $this->destTypeId, User::$id, $w, $h, diff --git a/endpoints/signature/delete.php b/endpoints/signature/delete.php index 9a7fa17f..2b9a9506 100644 --- a/endpoints/signature/delete.php +++ b/endpoints/signature/delete.php @@ -23,7 +23,7 @@ class SignatureDeleteResponse extends TextResponse if (!$this->assertGET('id')) $this->generate404(); - // DB::Aowow()->query(DELETE FROM ?_account_signatures WHERE `id` IN (?a) { AND `accountId` = ?d }', $this->_get['id], User::isInGroup(U_GROUP_MODERATOR) ? DBSIMPLE_SKIP : User::$id); + // DB::Aowow()->qry(DELETE FROM ::account_signatures WHERE %if', !User::isInGroup(U_GROUP_MODERATOR), '`accountId` = %i AND', User::$id, '%end `id` IN %in', $this->_get['id]); } } diff --git a/endpoints/signature/signature.php b/endpoints/signature/signature.php index 520bbea2..e0a5b76b 100644 --- a/endpoints/signature/signature.php +++ b/endpoints/signature/signature.php @@ -46,7 +46,7 @@ class SignatureBaseResponse extends TemplateResponse $realms = Profiler::getRealms(); if ($rId = array_find_key($realms, fn($x) => $x['region'] == $region && $x['name'] == $realm)) - return DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_profiles WHERE `realm` = ?d AND `custom` = 0 AND `name` = ?', $rId, urldecode($char)) ?: null; + return DB::Aowow()->selectCell('SELECT `id` FROM ::profiler_profiles WHERE `realm` = %i AND `custom` = 0 AND `name` = %s', $rId, urldecode($char)) ?: null; return null; } diff --git a/endpoints/skill/skill.php b/endpoints/skill/skill.php index 74cc99a8..a95221bf 100644 --- a/endpoints/skill/skill.php +++ b/endpoints/skill/skill.php @@ -114,8 +114,8 @@ class SkillBaseResponse extends TemplateResponse implements ICache { // tab: recipes [spells] (crafted) $condition = array( - ['OR', ['s.reagent1', 0, '>'], ['s.reagent2', 0, '>'], ['s.reagent3', 0, '>'], ['s.reagent4', 0, '>'], ['s.reagent5', 0, '>'], ['s.reagent6', 0, '>'], ['s.reagent7', 0, '>'], ['s.reagent8', 0, '>']], - ['OR', ['s.skillLine1', $this->typeId], ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->typeId]]] + [DB::OR, ['s.reagent1', 0, '>'], ['s.reagent2', 0, '>'], ['s.reagent3', 0, '>'], ['s.reagent4', 0, '>'], ['s.reagent5', 0, '>'], ['s.reagent6', 0, '>'], ['s.reagent7', 0, '>'], ['s.reagent8', 0, '>']], + [DB::OR, ['s.skillLine1', $this->typeId], [DB::AND, ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->typeId]]] ); $recipes = new SpellList($condition); // also relevant for 3 @@ -221,10 +221,10 @@ class SkillBaseResponse extends TemplateResponse implements ICache // tab: modified by [spell] $conditions = array( - 'OR', - ['AND', ['effect1AuraId', [SPELL_AURA_MOD_SKILL, SPELL_AURA_MOD_SKILL_TALENT]], ['effect1MiscValue', $this->typeId]], - ['AND', ['effect2AuraId', [SPELL_AURA_MOD_SKILL, SPELL_AURA_MOD_SKILL_TALENT]], ['effect2MiscValue', $this->typeId]], - ['AND', ['effect3AuraId', [SPELL_AURA_MOD_SKILL, SPELL_AURA_MOD_SKILL_TALENT]], ['effect3MiscValue', $this->typeId]] + DB::OR, + [DB::AND, ['effect1AuraId', [SPELL_AURA_MOD_SKILL, SPELL_AURA_MOD_SKILL_TALENT]], ['effect1MiscValue', $this->typeId]], + [DB::AND, ['effect2AuraId', [SPELL_AURA_MOD_SKILL, SPELL_AURA_MOD_SKILL_TALENT]], ['effect2MiscValue', $this->typeId]], + [DB::AND, ['effect3AuraId', [SPELL_AURA_MOD_SKILL, SPELL_AURA_MOD_SKILL_TALENT]], ['effect3MiscValue', $this->typeId]] ); $modBy = new SpellList($conditions); if (!$modBy->error) @@ -243,15 +243,15 @@ class SkillBaseResponse extends TemplateResponse implements ICache $reqClass = 0x0; $reqRace = 0x0; $condition = array( - ['AND', ['s.reagent1', 0], ['s.reagent2', 0], ['s.reagent3', 0], ['s.reagent4', 0], ['s.reagent5', 0], ['s.reagent6', 0], ['s.reagent7', 0], ['s.reagent8', 0]], - ['OR', ['s.skillLine1', $this->typeId], ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->typeId]]] + [DB::AND, ['s.reagent1', 0], ['s.reagent2', 0], ['s.reagent3', 0], ['s.reagent4', 0], ['s.reagent5', 0], ['s.reagent6', 0], ['s.reagent7', 0], ['s.reagent8', 0]], + [DB::OR, ['s.skillLine1', $this->typeId], [DB::AND, ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->typeId]]] ); foreach (Game::$skillLineMask as $line1 => $sets) foreach ($sets as $idx => [, $skillLineId]) if ($skillLineId == $this->typeId) { - $condition[1][] = array('AND', ['s.skillLine1', $line1], ['s.skillLine2OrMask', 1 << $idx, '&']); + $condition[1][] = array(DB::AND, ['s.skillLine1', $line1], ['s.skillLine2OrMask', 1 << $idx, '&']); break 2; } @@ -292,13 +292,12 @@ class SkillBaseResponse extends TemplateResponse implements ICache $mask |= 1 << $idx; $spellIds = DB::Aowow()->selectCol( - 'SELECT `id` FROM ?_spell WHERE (`skillLine1` = ?d OR (`skillLine1` > 0 AND `skillLine2OrMask` = ?d) {OR (`skillLine1` = -3 AND `skillLine2OrMask` = ?d)})', + 'SELECT `id` FROM ::spell WHERE %if', $mask, '(`skillLine1` = -3 AND `skillLine2OrMask` = %i) OR', $mask, '%end (`skillLine1` = %i OR (`skillLine1` > 0 AND `skillLine2OrMask` = %i))', $this->typeId, - $this->typeId, - $mask ?: DBSIMPLE_SKIP + $this->typeId ); - $list = $spellIds ? DB::World()->selectCol('SELECT cdt.`CreatureId` FROM creature_default_trainer cdt JOIN trainer_spell ts ON ts.`TrainerId` = cdt.`TrainerId` WHERE ts.`SpellID` IN (?a)', $spellIds) : []; + $list = $spellIds ? DB::World()->selectCol('SELECT cdt.`CreatureId` FROM creature_default_trainer cdt JOIN trainer_spell ts ON ts.`TrainerId` = cdt.`TrainerId` WHERE ts.`SpellID` IN %in', $spellIds) : []; if ($list) { $trainer = new CreatureList(array(['ct.id', $list], ['s.guid', NULL, '!'], ['ct.npcflag', 0x10, '&'])); diff --git a/endpoints/sound/sound.php b/endpoints/sound/sound.php index aa79fe73..8db7cf8f 100644 --- a/endpoints/sound/sound.php +++ b/endpoints/sound/sound.php @@ -80,7 +80,7 @@ class SoundBaseResponse extends TemplateResponse implements ICache } // get full path in-game for sound (workaround for missing PlaySoundKit()) - $fullpath = DB::Aowow()->selectCell('SELECT IF(sf.`path` <> "", CONCAT(sf.`path`, "\\\\", sf.`file`), sf.`file`) FROM ?_sounds_files sf JOIN ?_sounds s ON s.`soundFile1` = sf.`id` WHERE s.`id` = ?d', $this->typeId); + $fullpath = DB::Aowow()->selectCell('SELECT IF(sf.`path` <> "", CONCAT(sf.`path`, "\\", sf.`file`), sf.`file`) FROM ::sounds_files sf JOIN ::sounds s ON s.`soundFile1` = sf.`id` WHERE s.`id` = %i', $this->typeId); $this->redButtons = array( BUTTON_WOWHEAD => true, @@ -107,25 +107,25 @@ class SoundBaseResponse extends TemplateResponse implements ICache // skipping (always empty): ready, castertargeting, casterstate, targetstate $displayIds = DB::Aowow()->selectCol( 'SELECT `id` - FROM ?_spell_sounds - WHERE `animation` = ?d OR `precast` = ?d OR `cast` = ?d OR `impact` = ?d OR `state` = ?d OR - `statedone` = ?d OR `channel` = ?d OR `casterimpact` = ?d OR `targetimpact` = ?d OR `missiletargeting` = ?d OR - `instantarea` = ?d OR `persistentarea` = ?d OR `missile` = ?d OR `impactarea` = ?d', + FROM ::spell_sounds + WHERE `animation` = %i OR `precast` = %i OR `cast` = %i OR `impact` = %i OR `state` = %i OR + `statedone` = %i OR `channel` = %i OR `casterimpact` = %i OR `targetimpact` = %i OR `missiletargeting` = %i OR + `instantarea` = %i OR `persistentarea` = %i OR `missile` = %i OR `impactarea` = %i', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId ); $seMiscValues = DB::Aowow()->selectCol( 'SELECT `id` - FROM ?_screeneffect_sounds - WHERE `ambienceDay` = ?d OR `ambienceNight` = ?d OR `musicDay` = ?d OR `musicNight` = ?d', + FROM ::screeneffect_sounds + WHERE `ambienceDay` = %i OR `ambienceNight` = %i OR `musicDay` = %i OR `musicNight` = %i', $this->typeId, $this->typeId, $this->typeId, $this->typeId ); $cnd = array( - 'OR', - ['AND', ['effect1Id', [SPELL_EFFECT_PLAY_MUSIC, SPELL_EFFECT_PLAY_SOUND]], ['effect1MiscValue', $this->typeId]], - ['AND', ['effect2Id', [SPELL_EFFECT_PLAY_MUSIC, SPELL_EFFECT_PLAY_SOUND]], ['effect2MiscValue', $this->typeId]], - ['AND', ['effect3Id', [SPELL_EFFECT_PLAY_MUSIC, SPELL_EFFECT_PLAY_SOUND]], ['effect3MiscValue', $this->typeId]] + DB::OR, + [DB::AND, ['effect1Id', [SPELL_EFFECT_PLAY_MUSIC, SPELL_EFFECT_PLAY_SOUND]], ['effect1MiscValue', $this->typeId]], + [DB::AND, ['effect2Id', [SPELL_EFFECT_PLAY_MUSIC, SPELL_EFFECT_PLAY_SOUND]], ['effect2MiscValue', $this->typeId]], + [DB::AND, ['effect3Id', [SPELL_EFFECT_PLAY_MUSIC, SPELL_EFFECT_PLAY_SOUND]], ['effect3MiscValue', $this->typeId]] ); if ($displayIds) @@ -133,10 +133,10 @@ class SoundBaseResponse extends TemplateResponse implements ICache if ($seMiscValues) $cnd[] = array( - 'OR', - ['AND', ['effect1AuraId', SPELL_AURA_SCREEN_EFFECT], ['effect1MiscValue', $seMiscValues]], - ['AND', ['effect2AuraId', SPELL_AURA_SCREEN_EFFECT], ['effect2MiscValue', $seMiscValues]], - ['AND', ['effect3AuraId', SPELL_AURA_SCREEN_EFFECT], ['effect3MiscValue', $seMiscValues]] + DB::OR, + [DB::AND, ['effect1AuraId', SPELL_AURA_SCREEN_EFFECT], ['effect1MiscValue', $seMiscValues]], + [DB::AND, ['effect2AuraId', SPELL_AURA_SCREEN_EFFECT], ['effect2MiscValue', $seMiscValues]], + [DB::AND, ['effect3AuraId', SPELL_AURA_SCREEN_EFFECT], ['effect3MiscValue', $seMiscValues]] ); $spells = new SpellList($cnd); @@ -148,20 +148,23 @@ class SoundBaseResponse extends TemplateResponse implements ICache // tab: Items $subClasses = []; - if ($subClassMask = DB::Aowow()->selectCell('SELECT `subClassMask` FROM ?_items_sounds WHERE `soundId` = ?d', $this->typeId)) + if ($subClassMask = DB::Aowow()->selectCell('SELECT `subClassMask` FROM ::items_sounds WHERE `soundId` = %i', $this->typeId)) for ($i = 0; $i <= 20; $i++) if ($subClassMask & (1 << $i)) $subClasses[] = $i; - $itemIds = DB::Aowow()->selectCol( - 'SELECT id - FROM ?_items - WHERE `pickUpSoundId` = ?d OR `dropDownSoundId` = ?d OR `sheatheSoundId` = ?d OR `unsheatheSoundId` = ?d - { OR `spellVisualId` IN (?a) } - { OR (IF (`soundOverrideSubclass` > 0, `soundOverrideSubclass`, `subclass`) IN (?a) AND `class` = ?d) }', - $this->typeId, $this->typeId, $this->typeId, $this->typeId, $displayIds ?: DBSIMPLE_SKIP, $subClasses ?: DBSIMPLE_SKIP, ITEM_CLASS_WEAPON + $where = array( + ['`pickUpSoundId` = %i', $this->typeId], + ['`dropDownSoundId` = %i', $this->typeId], + ['`sheatheSoundId` = %i', $this->typeId], + ['`unsheatheSoundId` = %i', $this->typeId] ); - if ($itemIds) + if ($displayIds) + $where[] = ['`spellVisualId` IN %in', $displayIds]; + if ($subClasses) + $where[] = [DB::AND, [['IF (`soundOverrideSubclass` > 0, `soundOverrideSubclass`, `subclass`) IN %in', $subClasses], ['`class` = %i', ITEM_CLASS_WEAPON]]]; + + if ($itemIds = DB::Aowow()->selectCol('SELECT `id` FROM ::items WHERE %or', $where)) { $items = new ItemList(array(['id', $itemIds])); if (!$items->error) @@ -172,7 +175,7 @@ class SoundBaseResponse extends TemplateResponse implements ICache } // tab: Zones - if ($zoneIds = DB::Aowow()->select('SELECT `id`, `worldStateId`, `worldStateValue` FROM ?_zones_sounds WHERE `ambienceDay` = ?d OR `ambienceNight` = ?d OR `musicDay` = ?d OR `musicNight` = ?d OR `intro` = ?d', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId)) + if ($zoneIds = DB::Aowow()->selectAssoc('SELECT `id`, `worldStateId`, `worldStateValue` FROM ::zones_sounds WHERE `ambienceDay` = %i OR `ambienceNight` = %i OR `musicDay` = %i OR `musicNight` = %i OR `intro` = %i', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId)) { $zones = new ZoneList(array(['id', array_column($zoneIds, 'id')])); if (!$zones->error) @@ -235,7 +238,7 @@ class SoundBaseResponse extends TemplateResponse implements ICache } // tab: Races (VocalUISounds (containing error voice overs)) - if ($vo = DB::Aowow()->selectCol('SELECT `raceId` FROM ?_races_sounds WHERE `soundId` = ?d GROUP BY `raceId`', $this->typeId)) + if ($vo = DB::Aowow()->selectCol('SELECT `raceId` FROM ::races_sounds WHERE `soundId` = %i GROUP BY `raceId`', $this->typeId)) { $races = new CharRaceList(array(['id', $vo])); if (!$races->error) @@ -246,7 +249,7 @@ class SoundBaseResponse extends TemplateResponse implements ICache } // tab: Emotes (EmotesTextSound (containing emote audio)) - if ($em = DB::Aowow()->selectCol('SELECT `emoteId` FROM ?_emotes_sounds WHERE `soundId` = ?d GROUP BY `emoteId` UNION SELECT `id` FROM ?_emotes WHERE `soundId` = ?d', $this->typeId, $this->typeId)) + if ($em = DB::Aowow()->selectCol('SELECT `emoteId` FROM ::emotes_sounds WHERE `soundId` = %i GROUP BY `emoteId` UNION SELECT `id` FROM ::emotes WHERE `soundId` = %i', $this->typeId, $this->typeId)) { $races = new EmoteList(array(['id', $em])); if (!$races->error) @@ -259,7 +262,7 @@ class SoundBaseResponse extends TemplateResponse implements ICache } } - $creatureIds = DB::World()->selectCol('SELECT ct.`CreatureID` FROM creature_text ct LEFT JOIN broadcast_text bct ON bct.`ID` = ct.`BroadCastTextId` WHERE bct.`SoundEntriesID` = ?d OR ct.`Sound` = ?d', $this->typeId, $this->typeId); + $creatureIds = DB::World()->selectCol('SELECT ct.`CreatureID` FROM creature_text ct LEFT JOIN broadcast_text bct ON bct.`ID` = ct.`BroadCastTextId` WHERE bct.`SoundEntriesID` = %i OR ct.`Sound` = %i', $this->typeId, $this->typeId); // can objects or areatrigger play sound...? if ($goosp = SmartAI::getOwnerOfSoundPlayed($this->typeId, Type::NPC)) @@ -269,12 +272,12 @@ class SoundBaseResponse extends TemplateResponse implements ICache // skipping (always empty): transforms, footsteps $displayIds = DB::Aowow()->selectCol( 'SELECT `id` - FROM ?_creature_sounds - WHERE `greeting` = ?d OR `farewell` = ?d OR `angry` = ?d OR `exertion` = ?d OR `exertioncritical` = ?d OR - `injury` = ?d OR `injurycritical` = ?d OR `death` = ?d OR `stun` = ?d OR `stand` = ?d OR - `aggro` = ?d OR `wingflap` = ?d OR `wingglide` = ?d OR `alert` = ?d OR `fidget` = ?d OR - `customattack` = ?d OR `loop` = ?d OR `jumpstart` = ?d OR `jumpend` = ?d OR `petattack` = ?d OR - `petorder` = ?d OR `petdismiss` = ?d OR `birth` = ?d OR `spellcast` = ?d OR `submerge` = ?d OR `submerged` = ?d', + FROM ::creature_sounds + WHERE `greeting` = %i OR `farewell` = %i OR `angry` = %i OR `exertion` = %i OR `exertioncritical` = %i OR + `injury` = %i OR `injurycritical` = %i OR `death` = %i OR `stun` = %i OR `stand` = %i OR + `aggro` = %i OR `wingflap` = %i OR `wingglide` = %i OR `alert` = %i OR `fidget` = %i OR + `customattack` = %i OR `loop` = %i OR `jumpstart` = %i OR `jumpend` = %i OR `petattack` = %i OR + `petorder` = %i OR `petdismiss` = %i OR `birth` = %i OR `spellcast` = %i OR `submerge` = %i OR `submerged` = %i', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId, @@ -297,7 +300,7 @@ class SoundBaseResponse extends TemplateResponse implements ICache $extra[] = ['displayId1', $displayIds]; if (count($extra) > 1) - array_unshift($extra, 'OR'); + array_unshift($extra, DB::OR); else $extra = array_pop($extra); diff --git a/endpoints/spell/spell.php b/endpoints/spell/spell.php index 6e6517d3..fb5247b1 100644 --- a/endpoints/spell/spell.php +++ b/endpoints/spell/spell.php @@ -69,13 +69,13 @@ class SpellBaseResponse extends TemplateResponse implements ICache $this->extendGlobalData($jsg, $extra); $this->modelInfo = $this->subject->getModelInfo($this->typeId); - if ($spelldifficulty = DB::Aowow()->select( // has difficulty versions of itself + if ($spelldifficulty = DB::Aowow()->selectAssoc( // has difficulty versions of itself 'SELECT `normal10` AS "0", `normal25` AS "1", `heroic10` AS "2", `heroic25` AS "3", `mapType` AS ARRAY_KEY - FROM ?_spelldifficulty - WHERE `normal10` = ?d OR `normal25` = ?d OR - `heroic10` = ?d OR `heroic25` = ?d', + FROM ::spelldifficulty + WHERE `normal10` = %i OR `normal25` = %i OR + `heroic10` = %i OR `heroic25` = %i', $this->typeId, $this->typeId, $this->typeId, $this->typeId )) { @@ -84,17 +84,17 @@ class SpellBaseResponse extends TemplateResponse implements ICache } // returns self or firstRank - if ($fr = DB::World()->selectCell('SELECT `first_spell_id` FROM spell_ranks WHERE `spell_id` = ?d', $this->typeId)) + if ($fr = DB::World()->selectCell('SELECT `first_spell_id` FROM spell_ranks WHERE `spell_id` = %i', $this->typeId)) $this->firstRank = $fr; else $this->firstRank = DB::Aowow()->selectCell( 'SELECT IF(s1.`RankNo` <> 1 AND s2.`id`, s2.`id`, s1.`id`) - FROM ?_spell s1 - LEFT JOIN ?_spell s2 + FROM ::spell s1 + LEFT JOIN ::spell s2 ON s1.`SpellFamilyId` = s2.`SpelLFamilyId` AND s1.`SpellFamilyFlags1` = s2.`SpelLFamilyFlags1` AND s1.`SpellFamilyFlags2` = s2.`SpellFamilyFlags2` AND s1.`SpellFamilyFlags3` = s2.`SpellFamilyFlags3` AND s1.`name_loc0` = s2.`name_loc0` AND s2.`RankNo` = 1 - WHERE s1.`id` = ?d', + WHERE s1.`id` = %i', $this->typeId ); @@ -209,7 +209,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache /*************************/ // factionchange-equivalent - if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = ?d, `alliance_id`, -`horde_id`) FROM player_factionchange_spells WHERE `alliance_id` = ?d OR `horde_id` = ?d', $this->typeId, $this->typeId, $this->typeId)) + if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = %i, `alliance_id`, -`horde_id`) FROM player_factionchange_spells WHERE `alliance_id` = %i OR `horde_id` = %i', $this->typeId, $this->typeId, $this->typeId)) { $altSpell = new SpellList(array(['id', abs($pendant)])); if (!$altSpell->error) @@ -284,7 +284,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache $formSpells = []; for ($i = 1; $i < 4; $i++) if ($this->subject->getField('effect'.$i.'AuraId') == SPELL_AURA_MOD_SHAPESHIFT) - if ($_ = DB::Aowow()->selectRow('SELECT `spellId1`, `spellId2`, `spellId3`, `spellId4`, `spellId5`, `spellId6`, `spellId7`, `spellId8` FROM ?_shapeshiftforms WHERE `id` = ?d', $this->subject->getField('effect'.$i.'MiscValue'))) + if ($_ = DB::Aowow()->selectRow('SELECT `spellId1`, `spellId2`, `spellId3`, `spellId4`, `spellId5`, `spellId6`, `spellId7`, `spellId8` FROM ::shapeshiftforms WHERE `id` = %i', $this->subject->getField('effect'.$i.'MiscValue'))) $formSpells = array_merge($formSpells, $_); if ($formSpells) @@ -333,7 +333,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache $classSpells = $miscSpells = []; $this->effects[$i]['modifies'] = [&$classSpells, &$miscSpells]; - $sub = ['OR', ['s.spellFamilyFlags1', $m1, '&'], ['s.spellFamilyFlags2', $m2, '&'], ['s.spellFamilyFlags3', $m3, '&']]; + $sub = [DB::OR, ['s.spellFamilyFlags1', $m1, '&'], ['s.spellFamilyFlags2', $m2, '&'], ['s.spellFamilyFlags3', $m3, '&']]; $modSpells = new SpellList($conditions); if (!$modSpells->error) @@ -348,7 +348,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache if ($classSpells) { - foreach (DB::World()->select('SELECT `spell_id` AS ARRAY_KEY, `first_spell_id` AS "0", `rank` AS "1" FROM spell_ranks WHERE `spell_id` IN (?a)', array_keys($classSpells)) as $spellId => [$firstSpellId, $rank]) + foreach (DB::World()->selectAssoc('SELECT `spell_id` AS ARRAY_KEY, `first_spell_id` AS "0", `rank` AS "1" FROM spell_ranks WHERE `spell_id` IN %in', array_keys($classSpells)) as $spellId => [$firstSpellId, $rank]) { $classSpells[$firstSpellId][1][0] = min($classSpells[$firstSpellId][1][0] ?? $rank, $rank); $classSpells[$firstSpellId][1][1] = max($classSpells[$firstSpellId][1][1] ?? $rank, $rank); @@ -392,7 +392,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache } // tab: [$this is] modified by - $sub = ['OR']; + $sub = [DB::OR]; $conditions = [ ['s.typeCat', [-9], '!'], // GM (-9); also include uncategorized (0), NPC-Spell (-8)?; NPC includes totems, lightwell and others :/ ['s.spellFamilyId', $this->subject->getField('spellFamilyId')], @@ -409,10 +409,10 @@ class SpellBaseResponse extends TemplateResponse implements ICache continue; $sub[] = array( - 'AND', + DB::AND, ['s.effect'.$i.'AuraId', self::MOD_AURAS], [ - 'OR', + DB::OR, ['s.effect'.$i.'SpellClassMaskA', $m1, '&'], ['s.effect'.$i.'SpellClassMaskB', $m2, '&'], ['s.effect'.$i.'SpellClassMaskC', $m3, '&'] @@ -452,7 +452,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache ); if ($this->difficulties) - $conditions = ['OR', ['AND', ...$conditions], ['AND', ['s.id', $this->difficulties], ['s.id', $this->typeId, '!']]]; + $conditions = [DB::OR, [DB::AND, ...$conditions], [DB::AND, ['s.id', $this->difficulties], ['s.id', $this->typeId, '!']]]; $saSpells = new SpellList($conditions); if (!$saSpells->error) @@ -521,13 +521,13 @@ class SpellBaseResponse extends TemplateResponse implements ICache } // tab: glyphs - if ($gpIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_glyphproperties WHERE `spellId` = ?d', $this->typeId)) + if ($gpIds = DB::Aowow()->selectCol('SELECT `id` FROM ::glyphproperties WHERE `spellId` = %i', $this->typeId)) { $conditions = array( - 'OR', - ['AND', ['effect1Id', SPELL_EFFECT_APPLY_GLYPH], ['effect1MiscValue', $gpIds]], - ['AND', ['effect2Id', SPELL_EFFECT_APPLY_GLYPH], ['effect2MiscValue', $gpIds]], - ['AND', ['effect3Id', SPELL_EFFECT_APPLY_GLYPH], ['effect3MiscValue', $gpIds]] + DB::OR, + [DB::AND, ['effect1Id', SPELL_EFFECT_APPLY_GLYPH], ['effect1MiscValue', $gpIds]], + [DB::AND, ['effect2Id', SPELL_EFFECT_APPLY_GLYPH], ['effect2MiscValue', $gpIds]], + [DB::AND, ['effect3Id', SPELL_EFFECT_APPLY_GLYPH], ['effect3MiscValue', $gpIds]] ); $glyphSpells = new SpellList($conditions); if (!$glyphSpells->error) @@ -544,13 +544,13 @@ class SpellBaseResponse extends TemplateResponse implements ICache } // tab: used by - spell - if ($so = DB::Aowow()->selectCell('SELECT `id` FROM ?_spelloverride WHERE `spellId1` = ?d OR `spellId2` = ?d OR `spellId3` = ?d OR `spellId4` = ?d OR `spellId5` = ?d', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId)) + if ($so = DB::Aowow()->selectCell('SELECT `id` FROM ::spelloverride WHERE `spellId1` = %i OR `spellId2` = %i OR `spellId3` = %i OR `spellId4` = %i OR `spellId5` = %i', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId)) { $conditions = array( - 'OR', - ['AND', ['effect1AuraId', SPELL_AURA_OVERRIDE_SPELLS], ['effect1MiscValue', $so]], - ['AND', ['effect2AuraId', SPELL_AURA_OVERRIDE_SPELLS], ['effect2MiscValue', $so]], - ['AND', ['effect3AuraId', SPELL_AURA_OVERRIDE_SPELLS], ['effect3MiscValue', $so]] + DB::OR, + [DB::AND, ['effect1AuraId', SPELL_AURA_OVERRIDE_SPELLS], ['effect1MiscValue', $so]], + [DB::AND, ['effect2AuraId', SPELL_AURA_OVERRIDE_SPELLS], ['effect2MiscValue', $so]], + [DB::AND, ['effect3AuraId', SPELL_AURA_OVERRIDE_SPELLS], ['effect3MiscValue', $so]] ); $ubSpells = new SpellList($conditions); if (!$ubSpells->error) @@ -567,7 +567,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache // tab: used by - itemset $conditions = array( - 'OR', + DB::OR, ['spell1', $this->typeId], ['spell2', $this->typeId], ['spell3', $this->typeId], ['spell4', $this->typeId], ['spell5', $this->typeId], ['spell6', $this->typeId], ['spell7', $this->typeId], ['spell8', $this->typeId] ); @@ -586,12 +586,12 @@ class SpellBaseResponse extends TemplateResponse implements ICache // tab: used by - item $conditions = array( - 'OR', - ['AND', ['spellTrigger1', SPELL_TRIGGER_LEARN, '!'], ['spellId1', $this->typeId]], - ['AND', ['spellTrigger2', SPELL_TRIGGER_LEARN, '!'], ['spellId2', $this->typeId]], - ['AND', ['spellTrigger3', SPELL_TRIGGER_LEARN, '!'], ['spellId3', $this->typeId]], - ['AND', ['spellTrigger4', SPELL_TRIGGER_LEARN, '!'], ['spellId4', $this->typeId]], - ['AND', ['spellTrigger5', SPELL_TRIGGER_LEARN, '!'], ['spellId5', $this->typeId]] + DB::OR, + [DB::AND, ['spellTrigger1', SPELL_TRIGGER_LEARN, '!'], ['spellId1', $this->typeId]], + [DB::AND, ['spellTrigger2', SPELL_TRIGGER_LEARN, '!'], ['spellId2', $this->typeId]], + [DB::AND, ['spellTrigger3', SPELL_TRIGGER_LEARN, '!'], ['spellId3', $this->typeId]], + [DB::AND, ['spellTrigger4', SPELL_TRIGGER_LEARN, '!'], ['spellId4', $this->typeId]], + [DB::AND, ['spellTrigger5', SPELL_TRIGGER_LEARN, '!'], ['spellId5', $this->typeId]] ); $ubItems = new ItemList($conditions); @@ -608,7 +608,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache // tab: used by - object $conditions = array( - 'OR', + DB::OR, ['onUseSpell', $this->typeId], ['onSuccessSpell', $this->typeId], ['auraSpell', $this->typeId], ['triggeredSpell', $this->typeId] ); @@ -647,15 +647,15 @@ class SpellBaseResponse extends TemplateResponse implements ICache // tab: criteria of $conditions = array( - 'AND', + DB::AND, ['ac.type', [ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL] ], ['ac.value1', $this->typeId] ); - if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` IN (?a) AND `value1` = ?d', [ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA, ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA], $this->typeId)) - $conditions = ['OR', $conditions, ['ac.id', $extraCrt]]; + if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` IN %in AND `value1` = %i', [ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA, ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA], $this->typeId)) + $conditions = [DB::OR, $conditions, ['ac.id', $extraCrt]]; $coAchievemnts = new AchievementList($conditions); if (!$coAchievemnts->error) @@ -690,7 +690,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache } // tab: bonus loot - if ($extraItemData = DB::World()->select('SELECT `spellId` AS ARRAY_KEY, `additionalCreateChance` AS "0", `additionalMaxNum` AS "1" FROM skill_extra_item_template WHERE `requiredSpecialization` = ?d', $this->typeId)) + if ($extraItemData = DB::World()->selectAssoc('SELECT `spellId` AS ARRAY_KEY, `additionalCreateChance` AS "0", `additionalMaxNum` AS "1" FROM skill_extra_item_template WHERE `requiredSpecialization` = %i', $this->typeId)) { $extraSpells = new SpellList(array(['id', array_keys($extraItemData)])); if (!$extraSpells->error) @@ -719,7 +719,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache } // tab: exclusive with - if ($this->firstRank && DB::World()->selectCell('SELECT 1 FROM spell_group WHERE `spell_id` = ?d', $this->firstRank)) + if ($this->firstRank && DB::World()->selectCell('SELECT 1 FROM spell_group WHERE `spell_id` = %i', $this->firstRank)) { $groups = DB::World()->selectCol('SELECT `id` AS ARRAY_KEY, `spell_id` AS ARRAY_KEY2, `spell_id` FROM spell_group'); // unpack recursion @@ -741,12 +741,12 @@ class SpellBaseResponse extends TemplateResponse implements ICache if ($filtered = array_filter($groups, fn($x) => in_array($this->firstRank, $x))) { // get rule set - $rules = DB::World()->selectCol('SELECT `group_id` AS ARRAY_KEY, `stack_rule` FROM spell_group_stack_rules WHERE `group_id` IN (?a)', array_keys($filtered)); + $rules = DB::World()->selectCol('SELECT `group_id` AS ARRAY_KEY, `stack_rule` FROM spell_group_stack_rules WHERE `group_id` IN %in', array_keys($filtered)); // only use groups that have rules set if ($filtered = array_intersect_key($filtered, $rules)) { - $cnd = ['OR']; + $cnd = [DB::OR]; foreach ($filtered as $gr) $cnd[] = ['s.id', $gr]; @@ -786,10 +786,10 @@ class SpellBaseResponse extends TemplateResponse implements ICache } // tab: linked with - $rows = DB::World()->select( - 'SELECT `spell_trigger` AS "trigger", `spell_effect` AS "effect", `type`, IF(ABS(`spell_effect`) = ?d, ABS(`spell_trigger`), ABS(`spell_effect`)) AS "related" + $rows = DB::World()->selectAssoc( + 'SELECT `spell_trigger` AS "trigger", `spell_effect` AS "effect", `type`, IF(ABS(`spell_effect`) = %i, ABS(`spell_trigger`), ABS(`spell_effect`)) AS "related" FROM spell_linked_spell - WHERE ABS(`spell_effect`) = ?d OR ABS(`spell_trigger`) = ?d', + WHERE ABS(`spell_effect`) = %i OR ABS(`spell_trigger`) = %i', $this->typeId, $this->typeId, $this->typeId ); @@ -832,10 +832,10 @@ class SpellBaseResponse extends TemplateResponse implements ICache // tab: triggered by $conditions = array( - 'OR', - ['AND', ['OR', ['effect1Id', SpellList::EFFECTS_TRIGGER], ['effect1AuraId', SpellList::AURAS_TRIGGER]], ['effect1TriggerSpell', $this->typeId]], - ['AND', ['OR', ['effect2Id', SpellList::EFFECTS_TRIGGER], ['effect2AuraId', SpellList::AURAS_TRIGGER]], ['effect2TriggerSpell', $this->typeId]], - ['AND', ['OR', ['effect3Id', SpellList::EFFECTS_TRIGGER], ['effect3AuraId', SpellList::AURAS_TRIGGER]], ['effect3TriggerSpell', $this->typeId]], + DB::OR, + [DB::AND, [DB::OR, ['effect1Id', SpellList::EFFECTS_TRIGGER], ['effect1AuraId', SpellList::AURAS_TRIGGER]], ['effect1TriggerSpell', $this->typeId]], + [DB::AND, [DB::OR, ['effect2Id', SpellList::EFFECTS_TRIGGER], ['effect2AuraId', SpellList::AURAS_TRIGGER]], ['effect2TriggerSpell', $this->typeId]], + [DB::AND, [DB::OR, ['effect3Id', SpellList::EFFECTS_TRIGGER], ['effect3AuraId', SpellList::AURAS_TRIGGER]], ['effect3TriggerSpell', $this->typeId]], ); $trigger = new SpellList($conditions); @@ -852,17 +852,17 @@ class SpellBaseResponse extends TemplateResponse implements ICache // tab: used by - creature $conditions = array( - 'OR', + DB::OR, ['spell1', $this->typeId], ['spell2', $this->typeId], ['spell3', $this->typeId], ['spell4', $this->typeId], ['spell5', $this->typeId], ['spell6', $this->typeId], ['spell7', $this->typeId], ['spell8', $this->typeId] ); if (!empty($ubSAI[Type::NPC])) $conditions[] = ['id', $ubSAI[Type::NPC]]; - if ($auras = DB::World()->selectCol('SELECT `entry` FROM creature_template_addon WHERE `auras` REGEXP ?', '\\b'.$this->typeId.'\\b')) + if ($auras = DB::World()->selectCol('SELECT `entry` FROM creature_template_addon WHERE `auras` REGEXP %s', '\\b'.$this->typeId.'\\b')) $conditions[] = ['id', $auras]; - if ($spellClick = DB::World()->selectCol('SELECT `npc_entry` FROM npc_spellclick_spells WHERE `spell_id` = ?d', $this->typeId)) + if ($spellClick = DB::World()->selectCol('SELECT `npc_entry` FROM npc_spellclick_spells WHERE `spell_id` = %i', $this->typeId)) $conditions[] = ['id', $spellClick]; $ubCreature = new CreatureList($conditions); @@ -879,7 +879,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache } // tab: zone - if ($areaSpells = DB::World()->select('SELECT `area` AS ARRAY_KEY, `aura_spell` AS "0", `quest_start` AS "1", `quest_end` AS "2", `quest_start_status` AS "3", `quest_end_status` AS "4", `racemask` AS "5", `gender` AS "6" FROM spell_area WHERE `spell` = ?d', $this->typeId)) + if ($areaSpells = DB::World()->selectAssoc('SELECT `area` AS ARRAY_KEY, `aura_spell` AS "0", `quest_start` AS "1", `quest_end` AS "2", `quest_start_status` AS "3", `quest_end_status` AS "4", `racemask` AS "5", `gender` AS "6" FROM spell_area WHERE `spell` = %i', $this->typeId)) { $zones = new ZoneList(array(['id', array_keys($areaSpells)])); if (!$zones->error) @@ -1019,11 +1019,11 @@ class SpellBaseResponse extends TemplateResponse implements ICache // tab: taught by npc if ($this->subject->getRawSource(SRC_TRAINER)) { - $trainers = DB::World()->select( + $trainers = DB::World()->selectAssoc( 'SELECT cdt.`CreatureId` AS ARRAY_KEY, ts.`ReqSkillLine` AS "reqSkillId", ts.`ReqSkillRank` AS "reqSkillValue", ts.`ReqLevel` AS "reqLevel", ts.`ReqAbility1` AS "reqSpellId1", ts.`reqAbility2` AS "reqSpellId2" FROM creature_default_trainer cdt JOIN trainer_spell ts ON ts.`TrainerId` = cdt.`TrainerId` - WHERE ts.`SpellId` = ?d', + WHERE ts.`SpellId` = %i', $this->typeId ); @@ -1073,10 +1073,10 @@ class SpellBaseResponse extends TemplateResponse implements ICache // tab: taught by spell $conditions = array( - 'OR', - ['AND', ['effect1Id', SpellList::EFFECTS_TEACH], ['effect1TriggerSpell', $this->typeId]], - ['AND', ['effect2Id', SpellList::EFFECTS_TEACH], ['effect2TriggerSpell', $this->typeId]], - ['AND', ['effect3Id', SpellList::EFFECTS_TEACH], ['effect3TriggerSpell', $this->typeId]], + DB::OR, + [DB::AND, ['effect1Id', SpellList::EFFECTS_TEACH], ['effect1TriggerSpell', $this->typeId]], + [DB::AND, ['effect2Id', SpellList::EFFECTS_TEACH], ['effect2TriggerSpell', $this->typeId]], + [DB::AND, ['effect3Id', SpellList::EFFECTS_TEACH], ['effect3TriggerSpell', $this->typeId]], ); $tbSpell = new SpellList($conditions); @@ -1095,7 +1095,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache // tab: taught by quest $conditions = array( - 'OR', + DB::OR, ['sourceSpellId', $this->typeId], ['rewardSpell', $this->typeId], ['rewardSpellCast', $this->typeId] @@ -1117,12 +1117,12 @@ class SpellBaseResponse extends TemplateResponse implements ICache // tab: taught by item (i'd like to precheck $this->subject->sources, but there is no source:item only complicated crap like "drop" and "vendor") $conditions = array( - 'OR', - ['AND', ['spellTrigger1', SPELL_TRIGGER_LEARN], ['spellId1', $this->typeId]], - ['AND', ['spellTrigger2', SPELL_TRIGGER_LEARN], ['spellId2', $this->typeId]], - ['AND', ['spellTrigger3', SPELL_TRIGGER_LEARN], ['spellId3', $this->typeId]], - ['AND', ['spellTrigger4', SPELL_TRIGGER_LEARN], ['spellId4', $this->typeId]], - ['AND', ['spellTrigger5', SPELL_TRIGGER_LEARN], ['spellId5', $this->typeId]], + DB::OR, + [DB::AND, ['spellTrigger1', SPELL_TRIGGER_LEARN], ['spellId1', $this->typeId]], + [DB::AND, ['spellTrigger2', SPELL_TRIGGER_LEARN], ['spellId2', $this->typeId]], + [DB::AND, ['spellTrigger3', SPELL_TRIGGER_LEARN], ['spellId3', $this->typeId]], + [DB::AND, ['spellTrigger4', SPELL_TRIGGER_LEARN], ['spellId4', $this->typeId]], + [DB::AND, ['spellTrigger5', SPELL_TRIGGER_LEARN], ['spellId5', $this->typeId]], ); $tbItem = new ItemList($conditions); @@ -1139,10 +1139,10 @@ class SpellBaseResponse extends TemplateResponse implements ICache // tab: enchantments $conditions = array( - 'OR', - ['AND', ['type1', [ENCHANTMENT_TYPE_COMBAT_SPELL, ENCHANTMENT_TYPE_EQUIP_SPELL, ENCHANTMENT_TYPE_USE_SPELL]], ['object1', $this->typeId]], - ['AND', ['type2', [ENCHANTMENT_TYPE_COMBAT_SPELL, ENCHANTMENT_TYPE_EQUIP_SPELL, ENCHANTMENT_TYPE_USE_SPELL]], ['object2', $this->typeId]], - ['AND', ['type3', [ENCHANTMENT_TYPE_COMBAT_SPELL, ENCHANTMENT_TYPE_EQUIP_SPELL, ENCHANTMENT_TYPE_USE_SPELL]], ['object3', $this->typeId]] + DB::OR, + [DB::AND, ['type1', [ENCHANTMENT_TYPE_COMBAT_SPELL, ENCHANTMENT_TYPE_EQUIP_SPELL, ENCHANTMENT_TYPE_USE_SPELL]], ['object1', $this->typeId]], + [DB::AND, ['type2', [ENCHANTMENT_TYPE_COMBAT_SPELL, ENCHANTMENT_TYPE_EQUIP_SPELL, ENCHANTMENT_TYPE_USE_SPELL]], ['object2', $this->typeId]], + [DB::AND, ['type3', [ENCHANTMENT_TYPE_COMBAT_SPELL, ENCHANTMENT_TYPE_EQUIP_SPELL, ENCHANTMENT_TYPE_USE_SPELL]], ['object3', $this->typeId]] ); $enchList = new EnchantmentList($conditions); if (!$enchList->error) @@ -1160,9 +1160,9 @@ class SpellBaseResponse extends TemplateResponse implements ICache $seSounds = []; for ($i = 1; $i < 4; $i++) // sounds from screen effect if ($this->subject->getField('effect'.$i.'AuraId') == SPELL_AURA_SCREEN_EFFECT) - $seSounds = DB::Aowow()->selectRow('SELECT `ambienceDay`, `ambienceNight`, `musicDay`, `musicNight` FROM ?_screeneffect_sounds WHERE `id` = ?d', $this->subject->getField('effect'.$i.'MiscValue')); + $seSounds = DB::Aowow()->selectRow('SELECT `ambienceDay`, `ambienceNight`, `musicDay`, `musicNight` FROM ::screeneffect_sounds WHERE `id` = %i', $this->subject->getField('effect'.$i.'MiscValue')); - $activitySounds = DB::Aowow()->selectRow('SELECT * FROM ?_spell_sounds WHERE `id` = ?d', $this->subject->getField('spellVisualId')); + $activitySounds = DB::Aowow()->selectRow('SELECT * FROM ::spell_sounds WHERE `id` = %i', $this->subject->getField('spellVisualId')); array_shift($activitySounds); // remove id-column if ($soundIDs = $activitySounds + $seSounds) { @@ -1185,9 +1185,9 @@ class SpellBaseResponse extends TemplateResponse implements ICache // tab: unlocks (object or item) $lockIds = DB::Aowow()->selectCol( - 'SELECT `id` FROM ?_lock WHERE (`type1` = ?d AND `properties1` = ?d) OR - (`type2` = ?d AND `properties2` = ?d) OR (`type3` = ?d AND `properties3` = ?d) OR - (`type4` = ?d AND `properties4` = ?d) OR (`type5` = ?d AND `properties5` = ?d)', + 'SELECT `id` FROM ::lock WHERE (`type1` = %i AND `properties1` = %i) OR + (`type2` = %i AND `properties2` = %i) OR (`type3` = %i AND `properties3` = %i) OR + (`type4` = %i AND `properties4` = %i) OR (`type5` = %i AND `properties5` = %i)', LOCK_TYPE_SPELL, $this->typeId, LOCK_TYPE_SPELL, $this->typeId, LOCK_TYPE_SPELL, $this->typeId, LOCK_TYPE_SPELL, $this->typeId, LOCK_TYPE_SPELL, $this->typeId @@ -1196,9 +1196,9 @@ class SpellBaseResponse extends TemplateResponse implements ICache // we know this spell effect is only in use on index 1 if ($this->subject->getField('effect1Id') == SPELL_EFFECT_OPEN_LOCK && ($lockId = $this->subject->getField('effect1MiscValue'))) $lockIds += DB::Aowow()->selectCol( - 'SELECT `id` FROM ?_lock WHERE (`type1` = ?d AND `properties1` = ?d) OR - (`type2` = ?d AND `properties2` = ?d) OR (`type3` = ?d AND `properties3` = ?d) OR - (`type4` = ?d AND `properties4` = ?d) OR (`type5` = ?d AND `properties5` = ?d)', + 'SELECT `id` FROM ::lock WHERE (`type1` = %i AND `properties1` = %i) OR + (`type2` = %i AND `properties2` = %i) OR (`type3` = %i AND `properties3` = %i) OR + (`type4` = %i AND `properties4` = %i) OR (`type5` = %i AND `properties5` = %i)', LOCK_TYPE_SKILL, $lockId, LOCK_TYPE_SKILL, $lockId, LOCK_TYPE_SKILL, $lockId, LOCK_TYPE_SKILL, $lockId, LOCK_TYPE_SKILL, $lockId @@ -1296,9 +1296,9 @@ class SpellBaseResponse extends TemplateResponse implements ICache $item = DB::Aowow()->selectRow( 'SELECT `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, i.`id`, ic.`name` AS `iconString`, `quality`, `spellId1`, `spellCharges1` - FROM ?_items i - LEFT JOIN ?_icons ic ON ic.`id` = i.`iconId` - WHERE i.`id` = ?d', + FROM ::items i + LEFT JOIN ::icons ic ON ic.`id` = i.`iconId` + WHERE i.`id` = %i', $itemId ); @@ -1336,17 +1336,17 @@ class SpellBaseResponse extends TemplateResponse implements ICache { $level++; // assume that tradeSpells only use the first index to create items, so this runs somewhat efficiently >.< - $spells = DB::Aowow()->select( + $spells = DB::Aowow()->selectAssoc( 'SELECT `reagent1`, `reagent2`, `reagent3`, `reagent4`, `reagent5`, `reagent6`, `reagent7`, `reagent8`, `reagentCount1`, `reagentCount2`, `reagentCount3`, `reagentCount4`, `reagentCount5`, `reagentCount6`, `reagentCount7`, `reagentCount8`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `iconIdBak`, s.`id` AS ARRAY_KEY, ic.`name` AS `iconString` - FROM ?_spell s - JOIN ?_icons ic ON s.`iconId` = ic.`id` - WHERE (`effect1CreateItemId` = ?d AND `effect1Id` = ?d)',// OR - // (`effect2CreateItemId` = ?d AND `effect2Id` = ?d) OR - // (`effect3CreateItemId` = ?d AND `effect3Id` = ?d)', + FROM ::spell s + JOIN ::icons ic ON s.`iconId` = ic.`id` + WHERE (`effect1CreateItemId` = %i AND `effect1Id` = %i)',// OR + // (`effect2CreateItemId` = %i AND `effect2Id` = %i) OR + // (`effect3CreateItemId` = %i AND `effect3Id` = %i)', $itemId, SPELL_EFFECT_CREATE_ITEM //, $itemId, SPELL_EFFECT_CREATE_ITEM, $itemId, SPELL_EFFECT_CREATE_ITEM ); @@ -1469,7 +1469,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache $allDoTs = false; } - if ($s = DB::World()->selectRow('SELECT `direct_bonus` AS "0", `dot_bonus` AS "1", `ap_bonus` AS "2", `ap_dot_bonus` AS "3" FROM spell_bonus_data WHERE `entry` = ?d', $this->firstRank)) + if ($s = DB::World()->selectRow('SELECT `direct_bonus` AS "0", `dot_bonus` AS "1", `ap_bonus` AS "2", `ap_dot_bonus` AS "3" FROM spell_bonus_data WHERE `entry` = %i', $this->firstRank)) $scaling = $s; if (!in_array($this->subject->getField('typeCat'), [-2, -3, -7, 7]) || $this->subject->getField('damageClass') == SPELL_DAMAGE_CLASS_NONE) @@ -1590,7 +1590,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache 'cooldown' => 0 ); - if ($sp = DB::World()->selectRow('SELECT IF(`ProcsPerMinute` > 0, -`ProcsPerMinute`, `Chance`) AS "chance", `Cooldown` AS "cooldown" FROM `spell_proc` WHERE ABS(`SpellId`) = ?d', $this->firstRank)) + if ($sp = DB::World()->selectRow('SELECT IF(`ProcsPerMinute` > 0, -`ProcsPerMinute`, `Chance`) AS "chance", `Cooldown` AS "cooldown" FROM `spell_proc` WHERE ABS(`SpellId`) = %i', $this->firstRank)) { $procData['chance'] = $sp['chance'] ?: $procData['chance']; $procData['cooldown'] = $sp['cooldown'] ?: $procData['cooldown']; @@ -1599,7 +1599,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache $effects = []; $spellIdx = array_unique(array_merge($this->subject->canTriggerSpell(), $this->subject->canTeachSpell())); $itemIdx = $this->subject->canCreateItem(); - $perfItem = DB::World()->selectRow('SELECT `perfectItemType` AS "itemId", `requiredSpecialization` AS "reqSpellId", `perfectCreateChance` AS "chance" FROM skill_perfect_item_template WHERE `spellId` = ?d', $this->typeId); + $perfItem = DB::World()->selectRow('SELECT `perfectItemType` AS "itemId", `requiredSpecialization` AS "reqSpellId", `perfectCreateChance` AS "chance" FROM skill_perfect_item_template WHERE `spellId` = %i', $this->typeId); $scaling = $this->calculateEffectScaling(); // Iterate through all effects: @@ -1675,7 +1675,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache ); } } - else if ($extraItem = DB::World()->selectRow('SELECT * FROM skill_extra_item_template WHERE `spellid` = ?d', $this->typeId)) + else if ($extraItem = DB::World()->selectRow('SELECT * FROM skill_extra_item_template WHERE `spellid` = %i', $this->typeId)) { $cndSpell = new SpellList(array(['id', $extraItem['requiredSpecialization']])); if (!$cndSpell->error) @@ -1781,7 +1781,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache $effMVB = 67; // TC uses hardcoded summon property 67 // DO NOT BREAK ! case SPELL_EFFECT_SUMMON: - if (($sp = DB::Aowow()->selectRow('SELECT `control`, `slot` FROM ?_summonproperties WHERE `id` = ?d', $effMVB))) + if (($sp = DB::Aowow()->selectRow('SELECT `control`, `slot` FROM ::summonproperties WHERE `id` = %i', $effMVB))) $_nameMVB = $this->fmtStaffTip(Lang::spell('summonControl', $sp['control']).' – '.Lang::spell('summonSlot', $sp['slot']) , 'SummonProperty: '.$effMVB); // DO NOT BREAK ! case SPELL_EFFECT_SUMMON_DEMON: @@ -1830,7 +1830,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); break; case SPELL_EFFECT_APPLY_GLYPH: - if ($_ = DB::Aowow()->selectCell('SELECT `spellId` FROM ?_glyphproperties WHERE `id` = ?d', $effMV)) + if ($_ = DB::Aowow()->selectCell('SELECT `spellId` FROM ::glyphproperties WHERE `id` = %i', $effMV)) { if ($a = SpellList::makeLink($_)) $_nameMV = $a; @@ -1866,7 +1866,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache break; case SPELL_EFFECT_PLAY_SOUND: case SPELL_EFFECT_PLAY_MUSIC: - if (DB::Aowow()->selectCell('SELECT 1 FROM ?_sounds WHERE `id` = ?d', $effMV)) + if (DB::Aowow()->selectCell('SELECT 1 FROM ::sounds WHERE `id` = %i', $effMV)) { $_markup = '[sound='.$effMV.']'; $effMV = 0; // prevent default display @@ -1881,17 +1881,17 @@ class SpellBaseResponse extends TemplateResponse implements ICache $_nameMV = Util::ucFirst(Lang::game('faction')).' #'.$effMV; // apply custom reward rated - if ($cuRate = DB::World()->selectCell('SELECT `spell_rate` FROM reputation_reward_rate WHERE `spell_rate` <> 1 AND `faction` = ?d', $effMV)) + if ($cuRate = DB::World()->selectCell('SELECT `spell_rate` FROM reputation_reward_rate WHERE `spell_rate` <> 1 AND `faction` = %i', $effMV)) $_footer['value'][2] = sprintf(Util::$dfnString, Lang::faction('customRewRate'), ' ('.(($cuRate < 1 ? '-' : '+').intVal(($cuRate - 1) * $_footer['value'][0])).')'); break; case SPELL_EFFECT_SEND_TAXI: $_ = DB::Aowow()->selectRow( - 'SELECT tn1.`areaId` AS "startAreaId", tn1.`areaX` AS "startPosX", tn1.`areaY` AS "startPosY", tn1.`name_loc0` AS `start_loc0`, tn1.name_loc?d AS start_loc?d, - tn2.`areaId` AS "endAreaId", tn2.`areaX` AS "endPosX", tn2.`areaY` AS "endPosY", tn2.`name_loc0` AS `end_loc0`, tn2.name_loc?d AS end_loc?d - FROM ?_taxipath tp - JOIN ?_taxinodes tn1 ON tp.`startNodeId` = tn1.`id` - JOIN ?_taxinodes tn2 ON tp.`endNodeId` = tn2.`id` - WHERE tp.`id` = ?d', + 'SELECT tn1.`areaId` AS "startAreaId", tn1.`areaX` AS "startPosX", tn1.`areaY` AS "startPosY", tn1.`name_loc0` AS "start_loc0", tn1.name_loc%i AS start_loc%i, + tn2.`areaId` AS "endAreaId", tn2.`areaX` AS "endPosX", tn2.`areaY` AS "endPosY", tn2.`name_loc0` AS "end_loc0", tn2.name_loc%i AS end_loc%i + FROM ::taxipath tp + JOIN ::taxinodes tn1 ON tp.`startNodeId` = tn1.`id` + JOIN ::taxinodes tn2 ON tp.`endNodeId` = tn2.`id` + WHERE tp.`id` = %i', Lang::getLocale()->value, Lang::getLocale()->value, Lang::getLocale()->value, Lang::getLocale()->value, $effMV ); if ($_) @@ -2154,7 +2154,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache $_nameMV = Util::ucFirst(Lang::game('faction')).' #'.$effMV; break; // also breaks for SPELL_AURA_FORCE_REACTION case SPELL_AURA_OVERRIDE_SPELLS: - if ($so = DB::Aowow()->selectRow('SELECT `spellId1`, `spellId2`, `spellId3`, `spellId4`, `spellId5` FROM ?_spelloverride WHERE `id` = ?d', $effMV)) + if ($so = DB::Aowow()->selectRow('SELECT `spellId1`, `spellId2`, `spellId3`, `spellId4`, `spellId5` FROM ::spelloverride WHERE `id` = %i', $effMV)) { if ($so = array_filter($so)) { @@ -2181,7 +2181,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache trigger_error('unused case #'.$effMV.' found for aura #'.$effAura); break; case SPELL_AURA_SCREEN_EFFECT: - if ($ses = DB::Aowow()->selectRow('SELECT `name`, `ambienceDay` AS "0", IF(`ambienceNight` <> `ambienceDay`, `ambienceNight`, 0) AS "1", `musicDay` AS "2", IF(`musicNight` <> `musicDay`, `musicNight`, 0) AS "3" FROM ?_screeneffect_sounds WHERE `id` = ?d', $effMV)) + if ($ses = DB::Aowow()->selectRow('SELECT `name`, `ambienceDay` AS "0", IF(`ambienceNight` <> `ambienceDay`, `ambienceNight`, 0) AS "1", `musicDay` AS "2", IF(`musicNight` <> `musicDay`, `musicNight`, 0) AS "3" FROM ::screeneffect_sounds WHERE `id` = %i', $effMV)) { $_nameMV = $this->fmtStaffTip($ses['name'], 'MiscValue: '.$effMV); for ($j = 0; $j < 4; $j++) @@ -2422,12 +2422,12 @@ class SpellBaseResponse extends TemplateResponse implements ICache // spell focus if ($_ = $this->subject->getField('spellFocusObject')) { - if ($sfObj = DB::Aowow()->selectRow('SELECT * FROM ?_spellfocusobject WHERE `id` = ?d', $_)) + if ($sfObj = DB::Aowow()->selectRow('SELECT * FROM ::spellfocusobject WHERE `id` = %i', $_)) { $n = Util::localizedString($sfObj, 'name'); if (!is_null(GameObjectListFilter::getCriteriaIndex(50, $_))) $n = '[url=?objects&filter=cr=50;crs='.$_.';crv=0]'.$n.'[/url]'; - else if ($objId = DB::Aowow()->selectCell('SELECT `id` FROM ?_objects WHERE `spellFocusId` = ?d', $_)) + else if ($objId = DB::Aowow()->selectCell('SELECT `id` FROM ::objects WHERE `spellFocusId` = %i', $_)) $n = '[url=?object='.$objId.']'.$n.'[/url]'; $infobox[] = Lang::game('requires2').' '.$n; @@ -2484,8 +2484,8 @@ class SpellBaseResponse extends TemplateResponse implements ICache // profiler relateed (note that this is part of the cache. I don't think this is important enough to calc for every view) 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 `custom` = 0 AND `stub` = 0'); + $x = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ::profiler_completion_spells WHERE `spellId` = %i', $this->typeId); + $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 @@ -2514,7 +2514,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache // spell script if (User::isInGroup(U_GROUP_STAFF)) - if ($_ = DB::World()->selectCell('SELECT `ScriptName` FROM spell_script_names WHERE ABS(`spell_id`) = ?d', $this->firstRank)) + if ($_ = DB::World()->selectCell('SELECT `ScriptName` FROM spell_script_names WHERE ABS(`spell_id`) = %i', $this->firstRank)) $infobox[] = 'Script'.Lang::main('colon').$_; @@ -2526,7 +2526,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache if ($this->subject->getField('effect'.$i.'Id') == SPELL_EFFECT_APPLY_GLYPH) $glyphId = $this->subject->getField('effect'.$i.'MiscValue'); - if ($_ = DB::Aowow()->selectCell('SELECT ic.`name` FROM ?_glyphproperties gp JOIN ?_icons ic ON gp.`iconId` = ic.`id` WHERE gp.`spellId` = ?d { OR gp.`id` = ?d }', $this->typeId, $glyphId ?: DBSIMPLE_SKIP)) + if ($_ = DB::Aowow()->selectCell('SELECT ic.`name` FROM ::glyphproperties gp JOIN ::icons ic ON gp.`iconId` = ic.`id` WHERE %if', $glyphId, 'gp.`id` = %i OR', $glyphId, '%end gp.`spellId` = %i', $this->typeId)) if (file_exists('static/images/wow/Interface/Spellbook/'.$_.'.png')) $this->infobox->append('[img src='.Cfg::get('STATIC_URL').'/images/wow/Interface/Spellbook/'.$_.'.png border=0 float=center margin=15]'); } diff --git a/endpoints/spells/spells.php b/endpoints/spells/spells.php index b7c5674c..eadebde5 100644 --- a/endpoints/spells/spells.php +++ b/endpoints/spells/spells.php @@ -207,26 +207,26 @@ class SpellsBaseResponse extends TemplateResponse implements ICache { if ($skillLineId == $this->category[1]) { - $xCond = ['AND', ['s.skillLine1', $i], ['s.skillLine2OrMask', 1 << $idx, '&']]; + $xCond = [DB::AND, ['s.skillLine1', $i], ['s.skillLine2OrMask', 1 << $idx, '&']]; break; } } } $conditions[] = [ - 'OR', + DB::OR, $xCond, ['s.skillLine1', $this->category[1]], - ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->category[1]]] + [DB::AND, ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->category[1]]] ]; } else { $conditions[] = [ - 'OR', + DB::OR, ['s.skillLine1', [-1, -2]], ['s.skillLine1', $this->validCats[-3]], - ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->validCats[-3]]] + [DB::AND, ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->validCats[-3]]] ]; } @@ -248,16 +248,16 @@ class SpellsBaseResponse extends TemplateResponse implements ICache switch ($this->category[1]) { case 1: - $conditions[] = ['OR', - ['AND', ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED], ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, '!']], - ['AND', ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED], ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, '!']] + $conditions[] = [DB::OR, + [DB::AND, ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED], ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, '!']], + [DB::AND, ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED], ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, '!']] ]; break; case 2: - $conditions[] = ['OR', ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED], ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED]]; + $conditions[] = [DB::OR, ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED], ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED]]; break; case 3: - $conditions[] = ['AND', + $conditions[] = [DB::AND, ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED, '!'], ['effect2AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, '!'], ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED, '!'], ['effect3AuraId', SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED, '!'] ]; @@ -306,7 +306,7 @@ class SpellsBaseResponse extends TemplateResponse implements ICache if (isset($this->category[1])) { if ($this->category[1] == 6) // todo (med): we know Weapon(6) includes spell Shoot(3018), that has a mask; but really, ANY proficiency or petSkill should be in that mask so there is no need to differenciate - $conditions[] = ['OR', ['s.skillLine1', SpellList::$skillLines[$this->category[1]]], ['s.skillLine1', -3]]; + $conditions[] = [DB::OR, ['s.skillLine1', SpellList::$skillLines[$this->category[1]]], ['s.skillLine1', -3]]; else $conditions[] = ['s.skillLine1', SpellList::$skillLines[$this->category[1]]]; } @@ -339,24 +339,24 @@ class SpellsBaseResponse extends TemplateResponse implements ICache // $conditions[] = [ // [['s.attributes0', 0x80, '&'], 0], // ~SPELL_ATTR0_HIDDEN_CLIENTSIDE // ['s.attributes0', 0x20, '&'], // SPELL_ATTR0_TRADESPELL (DK: Runeforging) - // 'OR' + // DB::OR // ]; if (isset($this->category[2])) { $conditions[] = [ - 'OR', + DB::OR, ['s.skillLine1', $this->category[2]], - ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->category[2]]] + [DB::AND, ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->category[2]]] ]; } else if (isset($this->category[1])) { $conditions[] = [ - 'OR', + DB::OR, ['s.skillLine1', $this->validCats[7][$this->category[1]]], - ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->validCats[7][$this->category[1]]]] + [DB::AND, ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->validCats[7][$this->category[1]]]] ]; } @@ -370,9 +370,9 @@ class SpellsBaseResponse extends TemplateResponse implements ICache if (isset($this->category[1])) { $conditions[] = [ - 'OR', + DB::OR, ['s.skillLine1', $this->category[1]], - ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->category[1]]] + [DB::AND, ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->category[1]]] ]; if (!empty(self::SHORT_FILTER[$this->category[1]])) @@ -440,9 +440,9 @@ class SpellsBaseResponse extends TemplateResponse implements ICache array_push($visibleCols, 'level'); $conditions[] = [ - 'OR', + DB::OR, ['s.typeCat', 0], - ['AND', ['s.cuFlags', SPELL_CU_TRIGGERED, '&'], ['s.typeCat', [7, -2]]] + [DB::AND, ['s.cuFlags', SPELL_CU_TRIGGERED, '&'], ['s.typeCat', [7, -2]]] ]; break; diff --git a/endpoints/title/title.php b/endpoints/title/title.php index 29ff9678..21959316 100644 --- a/endpoints/title/title.php +++ b/endpoints/title/title.php @@ -90,8 +90,8 @@ class TitleBaseResponse extends TemplateResponse implements ICache // profiler relateed (note that this is part of the cache. I don't think this is important enough to calc for every view) 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 `custom` = 0 AND `stub` = 0'); + $x = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ::profiler_completion_titles WHERE `titleId` = %i', $this->typeId); + $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 @@ -116,7 +116,7 @@ class TitleBaseResponse extends TemplateResponse implements ICache ); // factionchange-equivalent - if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = ?d, `alliance_id`, -`horde_id`) FROM player_factionchange_titles WHERE `alliance_id` = ?d OR `horde_id` = ?d', $this->typeId, $this->typeId, $this->typeId)) + if ($pendant = DB::World()->selectCell('SELECT IF(`horde_id` = %i, `alliance_id`, -`horde_id`) FROM player_factionchange_titles WHERE `alliance_id` = %i OR `horde_id` = %i', $this->typeId, $this->typeId, $this->typeId)) { $altTitle = new TitleList(array(['id', abs($pendant)])); if (!$altTitle->error) @@ -153,7 +153,7 @@ class TitleBaseResponse extends TemplateResponse implements ICache } // tab: reward-from-achievement - if ($aIds = DB::World()->selectCol('SELECT `ID` FROM achievement_reward WHERE `TitleA` = ?d OR `TitleH` = ?d', $this->typeId, $this->typeId)) + if ($aIds = DB::World()->selectCol('SELECT `ID` FROM achievement_reward WHERE `TitleA` = %i OR `TitleH` = %i', $this->typeId, $this->typeId)) { $acvs = new AchievementList(array(['id', $aIds])); if (!$acvs->error) @@ -171,7 +171,7 @@ class TitleBaseResponse extends TemplateResponse implements ICache } // tab: criteria-of - if ($crt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` = ?d AND `value1` = ?d', ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE, $this->typeId)) + if ($crt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` = %i AND `value1` = %i', ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE, $this->typeId)) { $acvs = new AchievementList(array(['ac.id', $crt])); if (!$acvs->error) diff --git a/endpoints/top-users/top-users.php b/endpoints/top-users/top-users.php index 4d3be418..464fea0a 100644 --- a/endpoints/top-users/top-users.php +++ b/endpoints/top-users/top-users.php @@ -49,25 +49,25 @@ class TopusersBaseResponse extends TemplateResponse foreach ($tabs as [$time, $tabId, $tabName]) { // stuff received - $res = DB::Aowow()->select( + $res = DB::Aowow()->selectAssoc( 'SELECT a.`id` AS ARRAY_KEY, a.`username`, a.`userGroups` AS "groups", a.`joinDate` AS "creation", - SUM(r.`amount`) AS "reputation", SUM(IF(r.`action` = ?d, 1, 0)) AS "comments", SUM(IF(r.`action` = ?d, 1, 0)) AS "screenshots", SUM(IF(r.`action` = ?d, 1, 0)) AS "reports" - FROM ?_account_reputation r - JOIN ?_account a ON a.`id` = r.`userId` - { WHERE r.`date` > ?d } + SUM(r.`amount`) AS "reputation", SUM(IF(r.`action` = %i, 1, 0)) AS "comments", SUM(IF(r.`action` = %i, 1, 0)) AS "screenshots", SUM(IF(r.`action` = %i, 1, 0)) AS "reports" + FROM ::account_reputation r + JOIN ::account a ON a.`id` = r.`userId`', + SITEREP_ACTION_COMMENT, SITEREP_ACTION_SUBMIT_SCREENSHOT, SITEREP_ACTION_GOOD_REPORT, + '%if', $time, 'WHERE r.`date` > %i', $time, '%end GROUP BY a.`id` ORDER BY reputation DESC - LIMIT ?d', - SITEREP_ACTION_COMMENT, SITEREP_ACTION_SUBMIT_SCREENSHOT, SITEREP_ACTION_GOOD_REPORT, - $time ?: DBSIMPLE_SKIP, self::MAX_RESULTS + LIMIT %i', + self::MAX_RESULTS ); $data = []; if ($res) { // stuff given - $votes = DB::Aowow()->selectCol('SELECT `sourceB` AS ARRAY_KEY, SUM(1) FROM ?_account_reputation WHERE `action` IN (?a) AND `sourceB` IN (?a) { AND `date` > ?d } GROUP BY `sourceB`', - [SITEREP_ACTION_UPVOTED, SITEREP_ACTION_DOWNVOTED], array_keys($res), $time ?: DBSIMPLE_SKIP + $votes = DB::Aowow()->selectCol('SELECT `sourceB` AS ARRAY_KEY, SUM(1) FROM ::account_reputation WHERE %if', $time, '`date` > %i AND', $time, '%end `action` IN %in AND `sourceB` IN %in GROUP BY `sourceB`', + [SITEREP_ACTION_UPVOTED, SITEREP_ACTION_DOWNVOTED], array_keys($res), ); foreach ($res as $uId => &$r) { diff --git a/endpoints/upload/image-complete.php b/endpoints/upload/image-complete.php index 1c60a39e..ab9c111d 100644 --- a/endpoints/upload/image-complete.php +++ b/endpoints/upload/image-complete.php @@ -62,7 +62,7 @@ class UploadImagecompleteResponse extends TextResponse if (!$fSize) return false; - $newId = DB::Aowow()->query('INSERT INTO ?_account_avatars (`id`, `userId`, `name`, `when`, `size`) VALUES (?d, ?d, ?, ?d, ?d)', $this->newId, User::$id, 'Avatar '.$this->newId, time(), $fSize); + $newId = DB::Aowow()->qry('INSERT INTO ::account_avatars (`id`, `userId`, `name`, `when`, `size`) VALUES (%i, %i, %s, %i, %i)', $this->newId, User::$id, 'Avatar '.$this->newId, time(), $fSize); if (!is_int($newId)) { trigger_error('UploadImagecompleteResponse - avatar query failed', E_USER_ERROR); diff --git a/endpoints/upload/image-crop.php b/endpoints/upload/image-crop.php index edd6444b..cf7f8279 100644 --- a/endpoints/upload/image-crop.php +++ b/endpoints/upload/image-crop.php @@ -67,12 +67,12 @@ class UploadImagecropResponse extends TemplateResponse if (!AvatarMgr::loadUpload()) return Lang::main('intError'); - $n = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_account_avatars WHERE `userId` = ?d', User::$id); + $n = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ::account_avatars WHERE `userId` = %i', User::$id); if ($n && $n > Cfg::get('ACC_MAX_AVATAR_UPLOADS')) return Lang::main('intError'); // why is ++(<IntExpression>); illegal syntax? WHO KNOWS!? - $this->nextId = (DB::Aowow()->selectCell('SELECT MAX(`id`) FROM ?_account_avatars') ?: 0) + 1; + $this->nextId = (DB::Aowow()->selectCell('SELECT MAX(`id`) FROM ::account_avatars') ?: 0) + 1; if (!AvatarMgr::tempSaveUpload(['avatar', $this->nextId], $this->imgHash)) return Lang::main('intError'); diff --git a/endpoints/user/user.php b/endpoints/user/user.php index f286be2f..cff2c560 100644 --- a/endpoints/user/user.php +++ b/endpoints/user/user.php @@ -38,7 +38,7 @@ class UserBaseResponse extends TemplateResponse if (!$rawParam) $this->forwardToSignIn('user'); - if ($user = DB::Aowow()->selectRow('SELECT a.`id`, a.`username`, a.`consecutiveVisits`, a.`userGroups`, a.`avatar`, a.`avatarborder`, a.`wowicon`, a.`title`, a.`description`, a.`joinDate`, a.`prevLogin`, IFNULL(SUM(ar.`amount`), 0) AS "sumRep", a.`prevIP`, a.`email` FROM ?_account a LEFT JOIN ?_account_reputation ar ON a.`id` = ar.`userId` WHERE a.`id` <> 0 AND LOWER(a.`username`) = LOWER(?) GROUP BY a.`id`', $rawParam)) + if ($user = DB::Aowow()->selectRow('SELECT a.`id`, a.`username`, a.`consecutiveVisits`, a.`userGroups`, a.`avatar`, a.`avatarborder`, a.`wowicon`, a.`title`, a.`description`, a.`joinDate`, a.`prevLogin`, IFNULL(SUM(ar.`amount`), 0) AS "sumRep", a.`prevIP`, a.`email` FROM ::account a LEFT JOIN ::account_reputation ar ON a.`id` = ar.`userId` WHERE a.`id` <> 0 AND LOWER(a.`username`) = LOWER(%s) GROUP BY a.`id`', $rawParam)) $this->user = $user; else $this->generateNotFound(Lang::user('notFound', [Util::htmlEscape($rawParam)])); @@ -113,7 +113,7 @@ class UserBaseResponse extends TemplateResponse $avatarMore = match ((int)$this->user['avatar']) { 1 => $this->user['wowicon'], - 2 => DB::Aowow()->selectCell('SELECT `id` FROM ?_account_avatars WHERE `current` = 1 AND `userId` = ?d', $this->user['id']), + 2 => DB::Aowow()->selectCell('SELECT `id` FROM ::account_avatars WHERE `current` = 1 AND `userId` = %i', $this->user['id']), default => '' }; @@ -147,7 +147,7 @@ class UserBaseResponse extends TemplateResponse // Reputation changelog (params only for comment-events) if (User::$id == $this->user['id'] || User::isInGroup(U_GROUP_MODERATOR)) - if ($repData = DB::Aowow()->select('SELECT `action`, `amount`, `date` AS "when", IF(`action` IN (3, 4, 5), `sourceA`, 0) AS "param" FROM ?_account_reputation WHERE `userId` = ?d', $this->user['id'])) + if ($repData = DB::Aowow()->selectAssoc('SELECT `action`, `amount`, `date` AS "when", IF(`action` IN (3, 4, 5), `sourceA`, 0) AS "param" FROM ::account_reputation WHERE `userId` = %i', $this->user['id'])) { array_walk($repData, fn(&$x) => $x['when'] = date(Util::$dateFormatInternal, $x['when'])); $this->lvTabs->addListviewTab(new Listview(['data' => $repData], 'reputationhistory')); @@ -287,7 +287,7 @@ class UserBaseResponse extends TemplateResponse private function getCommentStats() : ?string { $co = DB::Aowow()->selectRow( - 'SELECT COUNT(DISTINCT c.`id`) AS "0", SUM(IFNULL(ur.`value`, 0)) AS "1" FROM ?_comments c LEFT JOIN ?_user_ratings ur ON ur.`entry` = c.`id` AND ur.`type` = ?d AND ur.`userId` <> 0 WHERE c.`replyTo` = 0 AND c.`userId` = ?d', + 'SELECT COUNT(DISTINCT c.`id`) AS "0", SUM(IFNULL(ur.`value`, 0)) AS "1" FROM ::comments c LEFT JOIN ::user_ratings ur ON ur.`entry` = c.`id` AND ur.`type` = %i AND ur.`userId` <> 0 WHERE c.`replyTo` = 0 AND c.`userId` = %i', RATING_COMMENT, $this->user['id'] ); @@ -305,7 +305,7 @@ class UserBaseResponse extends TemplateResponse private function getScreenshotStats() : ?string { $ss = DB::Aowow()->selectRow( - 'SELECT COUNT(*) AS "0", SUM(IF(`status` & ?d, 1, 0)) AS "1", SUM(IF(`status` & ?d, 0, 1)) AS "2" FROM ?_screenshots WHERE `userIdOwner` = ?d AND (`status` & ?d) = 0', + 'SELECT COUNT(*) AS "0", SUM(IF(`status` & %i, 1, 0)) AS "1", SUM(IF(`status` & %i, 0, 1)) AS "2" FROM ::screenshots WHERE `userIdOwner` = %i AND (`status` & %i) = 0', CC_FLAG_STICKY, CC_FLAG_APPROVED, $this->user['id'], CC_FLAG_DELETED ); @@ -336,7 +336,7 @@ class UserBaseResponse extends TemplateResponse private function getVideoStats() : ?string { $vi = DB::Aowow()->selectRow( - 'SELECT COUNT(*) AS "0", SUM(IF(`status` & ?d, 1, 0)) AS "1", SUM(IF(`status` & ?d, 0, 1)) AS "2" FROM ?_videos WHERE `userIdOwner` = ?d AND (`status` & ?d) = 0', + 'SELECT COUNT(*) AS "0", SUM(IF(`status` & %i, 1, 0)) AS "1", SUM(IF(`status` & %i, 0, 1)) AS "2" FROM ::videos WHERE `userIdOwner` = %i AND (`status` & %i) = 0', CC_FLAG_STICKY, CC_FLAG_APPROVED, $this->user['id'], CC_FLAG_DELETED ); diff --git a/endpoints/video/complete.php b/endpoints/video/complete.php index c36cb959..3bb554aa 100644 --- a/endpoints/video/complete.php +++ b/endpoints/video/complete.php @@ -60,13 +60,13 @@ class VideoCompleteResponse extends TextResponse if (!VideoMgr::loadSuggestion($videoInfo, $this->destType, $this->destTypeId, $this->videoHash)) $this->generate404(); - $pos = DB::Aowow()->selectCell('SELECT MAX(`pos`) FROM ?_videos WHERE `type` = ?d AND `typeId` = ?d AND (`status` & ?d) = 0', $this->destType, $this->destTypeId, CC_FLAG_DELETED); + $pos = DB::Aowow()->selectCell('SELECT MAX(`pos`) FROM ::videos WHERE `type` = %i AND `typeId` = %i AND (`status` & %i) = 0', $this->destType, $this->destTypeId, CC_FLAG_DELETED); if (!is_int($pos)) $pos = -1; // write to db - $newId = DB::Aowow()->query( - 'INSERT INTO ?_videos (`type`, `typeId`, `userIdOwner`, `date`, `videoId`, `pos`, `url`, `width`, `height`, `name`, `caption`, `status`) VALUES (?d, ?d, ?d, UNIX_TIMESTAMP(), ?, ?d, ?, ?d, ?d, ?, ?, 0)', + $newId = DB::Aowow()->qry( + 'INSERT INTO ::videos (`type`, `typeId`, `userIdOwner`, `date`, `videoId`, `pos`, `url`, `width`, `height`, `name`, `caption`, `status`) VALUES (%i, %i, %i, UNIX_TIMESTAMP(), %s, %i, %s, %i, %i, %s, %s, 0)', $this->destType, $this->destTypeId, User::$id, $videoInfo->id, $pos + 1, diff --git a/endpoints/zone/zone.php b/endpoints/zone/zone.php index eb2da5b8..3e54eb4f 100644 --- a/endpoints/zone/zone.php +++ b/endpoints/zone/zone.php @@ -74,7 +74,7 @@ class ZoneBaseResponse extends TemplateResponse implements ICache /* Infobox */ /***********/ - $quickFactsRows = DB::Aowow()->selectCol('SELECT `orderIdx` AS ARRAY_KEY, `row` FROM ?_quickfacts WHERE `type` = ?d AND `typeId` = ?d ORDER BY `orderIdx` ASC', $this->type, $this->typeId); + $quickFactsRows = DB::Aowow()->selectCol('SELECT `orderIdx` AS ARRAY_KEY, `row` FROM ::quickfacts WHERE `type` = %i AND `typeId` = %i ORDER BY `orderIdx` ASC', $this->type, $this->typeId); $quickFactsRows = preg_replace_callback('/\|L:(\w+)((:\w+)+)\|/i', function ($m) { [, $grp, $args] = $m; @@ -148,14 +148,14 @@ class ZoneBaseResponse extends TemplateResponse implements ICache } // Instances - if ($_ = DB::Aowow()->selectCol('SELECT `typeId` FROM ?_spawns WHERE `type`= ?d AND `areaId` = ?d ', Type::ZONE, $this->typeId)) + if ($_ = DB::Aowow()->selectCol('SELECT `typeId` FROM ::spawns WHERE `type`= %i AND `areaId` = %i ', Type::ZONE, $this->typeId)) { $this->extendGlobalIds(Type::ZONE, ...$_); $infobox[] = Lang::maps('Instances').Lang::main('colon').Lang::concat($_, Lang::CONCAT_NONE, fn($x) => "\n[zone=".$x."]"); } // start area - if ($_ = DB::Aowow()->selectCol('SELECT `id` FROM ?_races WHERE `startAreaId` = ?d', $this->typeId)) + if ($_ = DB::Aowow()->selectCol('SELECT `id` FROM ::races WHERE `startAreaId` = %i', $this->typeId)) { $this->extendGlobalIds(Type::CHR_RACE, ...$_); $infobox[] = Lang::concat($_, Lang::CONCAT_NONE, fn($x) => '[race='.$x.']').' '.Lang::race('startZone'); @@ -164,7 +164,7 @@ class ZoneBaseResponse extends TemplateResponse implements ICache parent::generate(); // calls applyGlobals .. probably too early here, but addMoveLocationMenu requires PageTemplate to be initialized // location (if instance) - if ($pa = DB::Aowow()->selectRow('SELECT `areaId`, `posX`, `posY`, `floor` FROM ?_spawns WHERE `type`= ?d AND `typeId` = ?d ', Type::ZONE, $this->typeId)) + if ($pa = DB::Aowow()->selectRow('SELECT `areaId`, `posX`, `posY`, `floor` FROM ::spawns WHERE `type`= %i AND `typeId` = %i ', Type::ZONE, $this->typeId)) { $this->addMoveLocationMenu($pa['areaId'], $pa['floor']); @@ -236,9 +236,9 @@ class ZoneBaseResponse extends TemplateResponse implements ICache } // we cannot fetch spawns via lists. lists are grouped by entry - $oSpawns = DB::Aowow()->select('SELECT * FROM ?_spawns WHERE `areaId` = ?d AND `type` = ?d AND `posX` > 0 AND `posY` > 0', $this->typeId, Type::OBJECT); - $cSpawns = DB::Aowow()->select('SELECT * FROM ?_spawns WHERE `areaId` = ?d AND `type` = ?d AND `posX` > 0 AND `posY` > 0', $this->typeId, Type::NPC); - $aSpawns = User::isInGroup(U_GROUP_STAFF) ? DB::Aowow()->select('SELECT * FROM ?_spawns WHERE `areaId` = ?d AND `type` = ?d AND `posX` > 0 AND `posY` > 0', $this->typeId, Type::AREATRIGGER) : []; + $oSpawns = DB::Aowow()->selectAssoc('SELECT * FROM ::spawns WHERE `areaId` = %i AND `type` = %i AND `posX` > 0 AND `posY` > 0', $this->typeId, Type::OBJECT); + $cSpawns = DB::Aowow()->selectAssoc('SELECT * FROM ::spawns WHERE `areaId` = %i AND `type` = %i AND `posX` > 0 AND `posY` > 0', $this->typeId, Type::NPC); + $aSpawns = User::isInGroup(U_GROUP_STAFF) ? DB::Aowow()->selectAssoc('SELECT * FROM ::spawns WHERE `areaId` = %i AND `type` = %i AND `posX` > 0 AND `posY` > 0', $this->typeId, Type::AREATRIGGER) : []; $conditions = [['s.areaId', $this->typeId]]; if (!User::isInGroup(U_GROUP_STAFF)) @@ -519,7 +519,7 @@ class ZoneBaseResponse extends TemplateResponse implements ICache return $n1 <=> $n2; }); - $paths = DB::Aowow()->select('SELECT n1.`typeId` AS "0", n2.`typeId` AS "1" FROM ?_taxipath p JOIN ?_taxinodes n1 ON n1.`id` = p.`startNodeId` JOIN ?_taxinodes n2 ON n2.`id` = p.`endNodeId` WHERE n1.`typeId` IN (?a) AND n2.`typeId` IN (?a)', array_keys($flightNodes), array_keys($flightNodes)); + $paths = DB::Aowow()->selectAssoc('SELECT n1.`typeId` AS "0", n2.`typeId` AS "1" FROM ::taxipath p JOIN ::taxinodes n1 ON n1.`id` = p.`startNodeId` JOIN ::taxinodes n2 ON n2.`id` = p.`endNodeId` WHERE n1.`typeId` IN %in AND n2.`typeId` IN %in', array_keys($flightNodes), array_keys($flightNodes)); foreach ($paths as $k => $path) { @@ -681,10 +681,10 @@ class ZoneBaseResponse extends TemplateResponse implements ICache // tab: starts-quest // select every quest starter, that is a drop - $questStartItem = DB::Aowow()->select( + $questStartItem = DB::Aowow()->selectAssoc( 'SELECT qse.`typeId` AS ARRAY_KEY, `moreType`, `moreTypeId`, `moreZoneId` - FROM ?_quests_startend qse JOIN ?_source src ON src.`type` = qse.`type` AND src.`typeId` = qse.`typeId` - WHERE src.`src2` IS NOT NULL AND qse.`type` = ?d AND (`moreZoneId` = ?d OR (`moreType` = ?d AND `moreTypeId` IN (?a)) OR (`moreType` = ?d AND `moreTypeId` IN (?a)))', + FROM ::quests_startend qse JOIN ::source src ON src.`type` = qse.`type` AND src.`typeId` = qse.`typeId` + WHERE src.`src2` IS NOT NULL AND qse.`type` = %i AND (`moreZoneId` = %i OR (`moreType` = %i AND `moreTypeId` IN %in) OR (`moreType` = %i AND `moreTypeId` IN %in))', Type::ITEM, $this->typeId, Type::NPC, array_unique(array_column($cSpawns, 'typeId')) ?: [0], Type::OBJECT, array_unique(array_column($oSpawns, 'typeId')) ?: [0] @@ -729,21 +729,21 @@ class ZoneBaseResponse extends TemplateResponse implements ICache // tab: achievements // tab: criteria-of - $conditions = array('OR', + $conditions = array(DB::OR, array( - 'AND', + DB::AND, ['ac.type', [ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE, ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA]], ['ac.value1', $this->typeId] ) ); - if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` = ?d AND `value1` = ?d', ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA, $this->typeId)) + if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` = %i AND `value1` = %i', ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA, $this->typeId)) $conditions[] = ['ac.id', $extraCrt]; if ($this->subject->getField('category') != MAP_TYPE_ZONE) { $conditions[] = array ( - 'AND', + DB::AND, ['ac.type', [ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA, ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA, ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP] @@ -751,7 +751,7 @@ class ZoneBaseResponse extends TemplateResponse implements ICache ['ac.value1', $this->subject->getField('mapId')] ); - if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` = ?d AND `value1` = ?d', ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID, $this->subject->getField('mapId'))) + if ($extraCrt = DB::World()->selectCol('SELECT `criteria_id` FROM achievement_criteria_data WHERE `type` = %i AND `value1` = %i', ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID, $this->subject->getField('mapId'))) $conditions[] = ['ac.id', $extraCrt]; } @@ -776,9 +776,9 @@ class ZoneBaseResponse extends TemplateResponse implements ICache $xCols = array_merge(['$Listview.extraCols.percent'], $fish->extraCols); $note = null; - if ($skill = DB::World()->selectCell('SELECT `skill` FROM skill_fishing_base_level WHERE `entry` = ?d', $this->typeId)) + if ($skill = DB::World()->selectCell('SELECT `skill` FROM skill_fishing_base_level WHERE `entry` = %i', $this->typeId)) $note = sprintf(Util::$lvTabNoteString, Lang::zone('fishingSkill'), Lang::formatSkillBreakpoints(Game::getBreakpointsForSkill(SKILL_FISHING, $skill), Lang::FMT_HTML)); - else if ($_parentArea && ($skill = DB::World()->selectCell('SELECT `skill` FROM skill_fishing_base_level WHERE `entry` = ?d', $_parentArea))) + else if ($_parentArea && ($skill = DB::World()->selectCell('SELECT `skill` FROM skill_fishing_base_level WHERE `entry` = %i', $_parentArea))) $note = sprintf(Util::$lvTabNoteString, Lang::zone('fishingSkill'), Lang::formatSkillBreakpoints(Game::getBreakpointsForSkill(SKILL_FISHING, $skill), Lang::FMT_HTML)); $this->lvTabs->addListviewTab(new Listview(array( @@ -793,7 +793,7 @@ class ZoneBaseResponse extends TemplateResponse implements ICache } // tab: spells - if ($saData = DB::World()->select('SELECT * FROM spell_area WHERE `area` = ?d', $this->typeId)) + if ($saData = DB::World()->selectAssoc('SELECT * FROM spell_area WHERE `area` = %i', $this->typeId)) { $spells = new SpellList(array(['id', array_column($saData, 'spell')])); if (!$spells->error) @@ -856,18 +856,18 @@ class ZoneBaseResponse extends TemplateResponse implements ICache $areaIds[] = $this->typeId; $soundIds = []; - $zoneMusic = DB::Aowow()->select( + $zoneMusic = DB::Aowow()->selectAssoc( 'SELECT x.`soundId` AS ARRAY_KEY, x.`soundId`, x.`worldStateId`, x.`worldStateValue`, x.`type` - FROM (SELECT `ambienceDay` AS "soundId", `worldStateId`, `worldStateValue`, 1 AS "type" FROM ?_zones_sounds WHERE `id` IN (?a) AND `ambienceDay` > 0 UNION - SELECT `ambienceNight` AS "soundId", `worldStateId`, `worldStateValue`, 1 AS "type" FROM ?_zones_sounds WHERE `id` IN (?a) AND `ambienceNight` > 0 UNION - SELECT `musicDay` AS "soundId", `worldStateId`, `worldStateValue`, 2 AS "type" FROM ?_zones_sounds WHERE `id` IN (?a) AND `musicDay` > 0 UNION - SELECT `musicNight` AS "soundId", `worldStateId`, `worldStateValue`, 2 AS "type" FROM ?_zones_sounds WHERE `id` IN (?a) AND `musicNight` > 0 UNION - SELECT `intro` AS "soundId", `worldStateId`, `worldStateValue`, 3 AS "type" FROM ?_zones_sounds WHERE `id` IN (?a) AND `intro` > 0) x + FROM (SELECT `ambienceDay` AS "soundId", `worldStateId`, `worldStateValue`, 1 AS "type" FROM ::zones_sounds WHERE `id` IN %in AND `ambienceDay` > 0 UNION + SELECT `ambienceNight` AS "soundId", `worldStateId`, `worldStateValue`, 1 AS "type" FROM ::zones_sounds WHERE `id` IN %in AND `ambienceNight` > 0 UNION + SELECT `musicDay` AS "soundId", `worldStateId`, `worldStateValue`, 2 AS "type" FROM ::zones_sounds WHERE `id` IN %in AND `musicDay` > 0 UNION + SELECT `musicNight` AS "soundId", `worldStateId`, `worldStateValue`, 2 AS "type" FROM ::zones_sounds WHERE `id` IN %in AND `musicNight` > 0 UNION + SELECT `intro` AS "soundId", `worldStateId`, `worldStateValue`, 3 AS "type" FROM ::zones_sounds WHERE `id` IN %in AND `intro` > 0) x GROUP BY x.soundId, x.worldStateId, x.worldStateValue', $areaIds, $areaIds, $areaIds, $areaIds, $areaIds ); - if ($sSpawns = DB::Aowow()->selectCol('SELECT `typeId` FROM ?_spawns WHERE `areaId` = ?d AND `type` = ?d', $this->typeId, Type::SOUND)) + if ($sSpawns = DB::Aowow()->selectCol('SELECT `typeId` FROM ::spawns WHERE `areaId` = %i AND `type` = %i', $this->typeId, Type::SOUND)) $soundIds = array_merge($soundIds, $sSpawns); if ($zoneMusic) diff --git a/endpoints/zones/zones.php b/endpoints/zones/zones.php index a58b64e9..0f58fd4a 100644 --- a/endpoints/zones/zones.php +++ b/endpoints/zones/zones.php @@ -117,15 +117,15 @@ class ZonesBaseResponse extends TemplateResponse implements ICache if ($mapFile) { $somData = ['flightmaster' => []]; - $nodes = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, tn.* FROM ?_taxinodes tn WHERE `mapId` = ?d AND `type` <> 0 AND `typeId` <> 0', $spawnMap); - $paths = DB::Aowow()->select( + $nodes = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, tn.* FROM ::taxinodes tn WHERE `mapId` = %i AND `type` <> 0 AND `typeId` <> 0', $spawnMap); + $paths = DB::Aowow()->selectAssoc( 'SELECT IF(tn1.`reactA` = tn1.`reactH` AND tn2.`reactA` = tn2.`reactH`, 1, 0) AS "neutral", tp.`startNodeId` AS "startId", tn1.`mapX` AS "startPosX", tn1.`mapY` AS "startPosY", tp.`endNodeId` AS "endId", tn2.`mapX` AS "endPosX", tn2.`mapY` AS "endPosY" - FROM ?_taxipath tp, ?_taxinodes tn1, ?_taxinodes tn2 + FROM ::taxipath tp, ::taxinodes tn1, ::taxinodes tn2 WHERE tn1.`Id` = tp.`endNodeId` AND tn2.`Id` = tp.`startNodeId` AND tn1.`type` <> 0 AND tn2.`type` <> 0 AND - (tp.`startNodeId` IN (?a) OR tp.`EndNodeId` IN (?a))', + (tp.`startNodeId` IN %in OR tp.`EndNodeId` IN %in)', array_keys($nodes), array_keys($nodes) ); diff --git a/includes/cfg.class.php b/includes/cfg.class.php index b1b45fd2..5a8de443 100644 --- a/includes/cfg.class.php +++ b/includes/cfg.class.php @@ -66,7 +66,7 @@ class Cfg if (!DB::isConnected(DB_AOWOW)) return; - $sets = DB::Aowow()->select('SELECT `key` AS ARRAY_KEY, `value` AS "0", `flags` AS "1", `cat` AS "2", `default` AS "3", `comment` AS "4" FROM ?_config ORDER BY `key` ASC'); + $sets = DB::Aowow()->selectAssoc('SELECT `key` AS ARRAY_KEY, `value` AS "0", `flags` AS "1", `cat` AS "2", `default` AS "3", `comment` AS "4" FROM ::config ORDER BY `key` ASC'); foreach ($sets as $key => [$value, $flags, $catg, $default, $comment]) { $php = $flags & self::FLAG_PHP; @@ -129,7 +129,7 @@ class Cfg return 'this configuration option cannot be set'; $flags = self::FLAG_TYPE_STRING | self::FLAG_PHP; - if (!is_int(DB::Aowow()->query('INSERT IGNORE INTO ?_config (`key`, `value`, `cat`, `flags`) VALUES (?, ?, ?d, ?d)', $key, $value, self::CAT_MISCELLANEOUS, $flags))) + if (!is_int(DB::Aowow()->qry('INSERT IGNORE INTO ::config (`key`, `value`, `cat`, `flags`) VALUES (%s, %s, %i, %i)', $key, $value, self::CAT_MISCELLANEOUS, $flags))) return 'internal error'; self::$store[$key] = [$value, $flags, self::CAT_MISCELLANEOUS, null, null]; @@ -155,7 +155,7 @@ class Cfg if (self::$store[$key][self::IDX_FLAGS] & self::FLAG_INTERNAL) return 'can\'t delete internal option'; - if (!DB::Aowow()->query('DELETE FROM ?_config WHERE `key` = ? AND (`flags` & ?d) = 0 AND (`flags` & ?d) > 0', $key, self::FLAG_PERSISTENT, self::FLAG_PHP)) + if (!DB::Aowow()->qry('DELETE FROM ::config WHERE `key` = %s AND (`flags` & %i) = 0 AND (`flags` & %i) > 0', $key, self::FLAG_PERSISTENT, self::FLAG_PHP)) return 'internal error'; unset(self::$store[$key]); @@ -175,9 +175,9 @@ class Cfg } if ($fromDB && $fullInfo) - return array_values(DB::Aowow()->selectRow('SELECT `value`, `flags`, `cat`, `default`, `comment` FROM ?_config WHERE `key` = ?', $key)); + return array_values(DB::Aowow()->selectRow('SELECT `value`, `flags`, `cat`, `default`, `comment` FROM ::config WHERE `key` = %s', $key)); if ($fromDB) - return DB::Aowow()->selectCell('SELECT `value` FROM ?_config WHERE `key` = ?', $key); + return DB::Aowow()->selectCell('SELECT `value` FROM ::config WHERE `key` = %s', $key); if ($fullInfo) return self::$store[$key]; @@ -205,7 +205,7 @@ class Cfg if ($flags & self::FLAG_REQUIRED && !strlen($value)) return 'empty value given for required config'; - DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', $value, $key); + DB::Aowow()->qry('UPDATE ::config SET `value` = %s WHERE `key` = %s', $value, $key); self::$store[$key][self::IDX_VALUE] = $value; // validate change @@ -220,7 +220,7 @@ class Cfg if ($errMsg) { // rollback change - DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', $oldValue, $key); + DB::Aowow()->qry('UPDATE ::config SET `value` = %s WHERE `key` = %s', $oldValue, $key); self::$store[$key][self::IDX_VALUE] = $oldValue; return $errMsg; @@ -261,7 +261,7 @@ class Cfg if (!($flags & Cfg::FLAG_TYPE_STRING)) $default = @eval('return ('.$default.');'); - DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', $default, $key); + DB::Aowow()->qry('UPDATE ::config SET `value` = %s WHERE `key` = %s', $default, $key); self::$store[$key][self::IDX_VALUE] = $default; // validate change @@ -276,7 +276,7 @@ class Cfg if ($errMsg) { // rollback change - DB::Aowow()->query('UPDATE ?_config SET `value` = ? WHERE `key` = ?', $oldValue, $key); + DB::Aowow()->qry('UPDATE ::config SET `value` = %s WHERE `key` = %s', $oldValue, $key); self::$store[$key][self::IDX_VALUE] = $oldValue; return $errMsg; @@ -480,9 +480,9 @@ class Cfg return true; $ok = true; - foreach (['?_spell', '?_items', '?_objects', '?_creature', '?_quests'] as $tbl) + foreach (['::spell', '::items', '::objects', '::creature', '::quests'] as $tbl) { - if (DB::Aowow()->selectRow('SHOW INDEX FROM ?# WHERE `column_name` = ? AND `index_type` = "FULLTEXT"', $tbl, 'name_loc4')) + if (DB::Aowow()->selectRow('SHOW INDEX FROM %n WHERE `column_name` = %s AND `index_type` = "FULLTEXT"', $tbl, 'name_loc4')) continue; $ok = false; diff --git a/includes/components/Conditions/Conditions.class.php b/includes/components/Conditions/Conditions.class.php index 4848063c..9512d766 100644 --- a/includes/components/Conditions/Conditions.class.php +++ b/includes/components/Conditions/Conditions.class.php @@ -238,13 +238,21 @@ class Conditions else return $this; - $this->rows = array_merge($this->rows, DB::World()->select( + $where = [['`SourceTypeOrReferenceId` IN %in', $type]]; + if ($group) + $where[] = ['`SourceGroup` IN %in', $group]; + if ($entry) + $where[] = ['`SourceEntry` IN %in', $entry]; + if ($id) + $where[] = ['`SourceId` IN %in', $id]; + + $this->rows = array_merge($this->rows, DB::World()->selectAssoc( 'SELECT `SourceTypeOrReferenceId`, `SourceEntry`, `SourceGroup`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ConditionStringValue1`, `NegativeCondition` FROM conditions - WHERE `SourceTypeOrReferenceId` IN (?a){ AND `SourceGroup` IN (?a)}{ AND `SourceEntry` IN (?a)}{ AND `SourceId` IN (?a)} + WHERE %and ORDER BY `SourceTypeOrReferenceId`, `SourceEntry`, `SourceGroup`, `ElseGroup` ASC', - $type, $group ?: DBSIMPLE_SKIP, $entry ?: DBSIMPLE_SKIP, $id ?: DBSIMPLE_SKIP + $where )); return $this; @@ -257,23 +265,23 @@ class Conditions if ($type === $cVal1 /* && (!$conditionIds || in_array($cId, $conditionIds)) */ ) { if ($cId == self::CHR_CLASS || $cId == self::CHR_RACE) - $lookups[] = sprintf("(c2.`ConditionTypeOrReference` = %d AND (c2.`ConditionValue1` & %d) > 0)", $cId, 1 << ($typeId - 1)); + $lookups[] = [DB::AND, [['c2.`ConditionTypeOrReference` = %i', $cId], ['(c2.`ConditionValue1` & %i) > 0', 1 << ($typeId - 1)]]]; else - $lookups[] = sprintf("(c2.`ConditionTypeOrReference` = %d AND c2.`ConditionValue1` = %d)", $cId, $typeId); + $lookups[] = [DB::AND, [['c2.`ConditionTypeOrReference` = %i', $cId], ['c2.`ConditionValue1` = %i', $typeId]]]; } if (!$lookups) return $this; - $this->rows = array_merge($this->rows, DB::World()->select(sprintf( + $this->rows = array_merge($this->rows, DB::World()->selectAssoc( 'SELECT c1.`SourceTypeOrReferenceId`, c1.`SourceEntry`, c1.`SourceGroup`, c1.`SourceId`, c1.`ElseGroup`, c1.`ConditionTypeOrReference`, c1.`ConditionTarget`, c1.`ConditionValue1`, c1.`ConditionValue2`, c1.`ConditionValue3`, c1.`ConditionStringValue1`, c1.`NegativeCondition` FROM conditions c1 JOIN conditions c2 ON c1.SourceTypeOrReferenceId = c2.SourceTypeOrReferenceId AND c1.SourceEntry = c2.SourceEntry AND c1.SourceGroup = c2.SourceGroup AND c1.SourceId = c2.SourceId - WHERE %s + WHERE %or GROUP BY `SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3` ORDER BY `SourceTypeOrReferenceId`, `SourceEntry`, `SourceGroup`, `ElseGroup` ASC', - implode(' OR ', $lookups)) + $lookups )); return $this; @@ -554,7 +562,7 @@ class Conditions $cVal1 = 10; else if ($cVal1 == 0 || $cVal1 == 1) // eastern kingdoms / kalimdor ; // cVal alrady correct - NOP - else if ($id = DB::Aowow()->selectCell('SELECT `id` FROM ?_zones WHERE `mapId` = ?d AND `parentArea` = 0 AND (`cuFlags` & ?d) = 0', $cVal1, CUSTOM_EXCLUDE_FOR_LISTVIEW)) + else if ($id = DB::Aowow()->selectCell('SELECT `id` FROM ::zones WHERE `mapId` = %i AND `parentArea` = 0 AND (`cuFlags` & %i) = 0', $cVal1, CUSTOM_EXCLUDE_FOR_LISTVIEW)) { // remap for instanced area - do not use List (pointless overhead) $this->jsGlobals[Type::ZONE][$id] = $id; @@ -593,7 +601,7 @@ class Conditions { if ($cVal1 == self::TYPEID_UNIT) { - if ($cVal3 && ($_ = DB::Aowow()->selectCell('SELECT `typeId` FROM ?_spawns WHERE `type` = ?d AND `guid` = ?d', Type::NPC, $cVal3))) + if ($cVal3 && ($_ = DB::Aowow()->selectCell('SELECT `typeId` FROM ::spawns WHERE `type` = %i AND `guid` = %i', Type::NPC, $cVal3))) $cVal2 = intVal($_); if ($cVal2) @@ -601,7 +609,7 @@ class Conditions } else if ($cVal1 == self::TYPEID_GAMEOBJECT) { - if ($cVal3 && ($_ = DB::Aowow()->selectCell('SELECT `typeId` FROM ?_spawns WHERE `type` = ?d AND `guid` = ?d', Type::OBJECT, $cVal3))) + if ($cVal3 && ($_ = DB::Aowow()->selectCell('SELECT `typeId` FROM ::spawns WHERE `type` = %i AND `guid` = %i', Type::OBJECT, $cVal3))) $cVal2 = intVal($_); if ($cVal2) @@ -622,7 +630,7 @@ class Conditions return false; } - if ($npcs = DB::Aowow()->selectCol('SELECT `id` FROM ?_creature WHERE `lootId` = ?d', $sGroup)) + if ($npcs = DB::Aowow()->selectCol('SELECT `id` FROM ::creature WHERE `lootId` = %i', $sGroup)) { $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; foreach ($npcs as $npcId) @@ -646,7 +654,7 @@ class Conditions return false; } - if ($items = DB::Aowow()->selectCol('SELECT `id` FROM ?_items WHERE `disenchantId` = ?d', $sGroup)) + if ($items = DB::Aowow()->selectCol('SELECT `id` FROM ::items WHERE `disenchantId` = %i', $sGroup)) { $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; foreach ($items as $itemId) @@ -670,7 +678,7 @@ class Conditions return false; } - if ($gos = DB::Aowow()->selectCol('SELECT `id` FROM ?_objects WHERE `lootId` = ?d', $sGroup)) + if ($gos = DB::Aowow()->selectCol('SELECT `id` FROM ::objects WHERE `lootId` = %i', $sGroup)) { $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; foreach ($gos as $goId) @@ -694,7 +702,7 @@ class Conditions return false; } - if ($quests = DB::Aowow()->selectCol('SELECT `id` FROM ?_quests WHERE `rewardMailTemplateId` = ?d', $sGroup)) + if ($quests = DB::Aowow()->selectCol('SELECT `id` FROM ::quests WHERE `rewardMailTemplateId` = %i', $sGroup)) { $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; foreach ($quests as $questId) @@ -718,7 +726,7 @@ class Conditions return false; } - if ($npcs = DB::Aowow()->selectCol('SELECT `id` FROM ?_creature WHERE `pickpocketLootId` = ?d', $sGroup)) + if ($npcs = DB::Aowow()->selectCol('SELECT `id` FROM ::creature WHERE `pickpocketLootId` = %i', $sGroup)) { $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; foreach ($npcs as $npcId) @@ -742,7 +750,7 @@ class Conditions return false; } - if ($npcs = DB::Aowow()->selectCol('SELECT `id` FROM ?_creature WHERE `skinLootId` = ?d', $sGroup)) + if ($npcs = DB::Aowow()->selectCol('SELECT `id` FROM ::creature WHERE `skinLootId` = %i', $sGroup)) { $group = $sGroup . ':' . $sEntry . ':' . $sId . ':' . $cTarget; foreach ($npcs as $npcId) diff --git a/includes/components/SmartAI/SmartAI.class.php b/includes/components/SmartAI/SmartAI.class.php index b3b01cc2..3bf9b55e 100644 --- a/includes/components/SmartAI/SmartAI.class.php +++ b/includes/components/SmartAI/SmartAI.class.php @@ -12,7 +12,7 @@ trait SmartHelper { private function resolveGuid(int $type, int $guid) : ?int { - if ($_ = DB::Aowow()->selectCell('SELECT `typeId` FROM ?_spawns WHERE `type` = ?d AND `guid` = ?d', $type, $guid)) + if ($_ = DB::Aowow()->selectCell('SELECT `typeId` FROM ::spawns WHERE `type` = %i AND `guid` = %i', $type, $guid)) return $_; trigger_error('SmartAI::resolveGuid - failed to resolve guid '.$guid.' of type '.$type, E_USER_WARNING); @@ -282,13 +282,13 @@ class SmartAI if ($this->baseEntry) // my parent handles base css $this->css = ''; - $raw = DB::World()->select( + $raw = DB::World()->selectAssoc( 'SELECT `id`, `link`, - `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, + `event_type`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_phase_mask`, `event_chance`, `event_flags`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o` FROM smart_scripts - WHERE `entryorguid` = ?d AND `source_type` = ?d + WHERE `entryorguid` = %i AND `source_type` = %i ORDER BY `id` ASC', $this->entry, $this->srcType); @@ -320,15 +320,15 @@ class SmartAI SmartAction::ACTION_MOUNT_TO_ENTRY_OR_MODEL => [1 => $npcId] ); - if ($npcGuids = DB::Aowow()->selectCol('SELECT `guid` FROM ?_spawns WHERE `type` = ?d AND `typeId` = ?d', Type::NPC, $npcId)) - if ($groups = DB::World()->selectCol('SELECT `groupId` FROM spawn_group WHERE `spawnType` = 0 AND `spawnId` IN (?a)', $npcGuids)) + if ($npcGuids = DB::Aowow()->selectCol('SELECT `guid` FROM ::spawns WHERE `type` = %i AND `typeId` = %i', Type::NPC, $npcId)) + if ($groups = DB::World()->selectCol('SELECT `groupId` FROM spawn_group WHERE `spawnType` = 0 AND `spawnId` IN %in', $npcGuids)) foreach ($groups as $g) $lookup[SmartAction::ACTION_SPAWN_SPAWNGROUP][1] = $g; $result = self::getActionOwner($lookup, $typeFilter); // can skip lookups for SmartAction::ACTION_SUMMON_CREATURE_GROUP as creature_summon_groups already contains summoner info - if ($sgs = DB::World()->select('SELECT `summonerType` AS "0", `summonerId` AS "1" FROM creature_summon_groups WHERE `entry` = ?d', $npcId)) + if ($sgs = DB::World()->selectAssoc('SELECT `summonerType` AS "0", `summonerId` AS "1" FROM creature_summon_groups WHERE `entry` = %i', $npcId)) foreach ($sgs as [$type, $typeId]) $result[$type][] = $typeId; @@ -344,8 +344,8 @@ class SmartAI SmartAction::ACTION_SUMMON_GO => [1 => $objectId] ); - if ($objGuids = DB::Aowow()->selectCol('SELECT `guid` FROM ?_spawns WHERE `type` = ?d AND `typeId` = ?d', Type::OBJECT, $objectId)) - if ($groups = DB::World()->selectCol('SELECT `groupId` FROM spawn_group WHERE `spawnType` = 1 AND `spawnId` IN (?a)', $objGuids)) + if ($objGuids = DB::Aowow()->selectCol('SELECT `guid` FROM ::spawns WHERE `type` = %i AND `typeId` = %i', Type::OBJECT, $objectId)) + if ($groups = DB::World()->selectCol('SELECT `groupId` FROM spawn_group WHERE `spawnType` = 1 AND `spawnId` IN %in', $objGuids)) foreach ($groups as $g) $lookup[SmartAction::ACTION_SPAWN_SPAWNGROUP][1] = $g; @@ -402,38 +402,62 @@ class SmartAI break; } + $where = $qParts = []; foreach ($lookup as $action => $params) { - $aq = '(`action_type` = '.(int)$action.' AND ('; $pq = []; + $aq = [DB::AND, [['`action_type` = %i', $action], [DB::OR, &$pq]]]; foreach ($params as $idx => $p) - $pq[] = '`action_param'.(int)$idx.'` = '.(int)$p; + $pq[] = ["`action_param$idx` = %i", $p]; - if ($pq) - $qParts[] = $aq.implode(' OR ', $pq).'))'; + $qParts[] = $aq; + unset($pq); } - $smartS = DB::World()->select(sprintf('SELECT `source_type` AS "0", `entryOrGUID` AS "1" FROM smart_scripts WHERE (%s){ AND `source_type` IN (?a)}', $qParts ? implode(' OR ', $qParts) : '0'), $genFilter ?: DBSIMPLE_SKIP); + if ($genFilter) + $where[] = ['`source_type` IN %in', $genFilter]; + if ($qParts) + $where[] = [DB::OR, $qParts]; + + $smartS = DB::World()->selectAssoc('SELECT `source_type` AS "0", `entryOrGUID` AS "1" FROM smart_scripts WHERE %and', $where ?: [0]); // filter for TAL shenanigans if ($smartTAL = array_filter($smartS, fn($x) => $x[0] == self::SRC_TYPE_ACTIONLIST)) { $smartS = array_diff_key($smartS, $smartTAL); - $q = []; + $q = $where = []; foreach ($smartTAL as [, $eog]) { // SmartAction::ACTION_CALL_TIMED_ACTIONLIST - $q[] = '`action_type` = '.SmartAction::ACTION_CALL_TIMED_ACTIONLIST.' AND `action_param1` = '.$eog; + $q[] = [DB::AND, array( + ['`action_type` = %i', SmartAction::ACTION_CALL_TIMED_ACTIONLIST], + ['`action_param1` = %i', $eog] + )]; // SmartAction::ACTION_CALL_RANDOM_TIMED_ACTIONLIST - $q[] = '`action_type` = '.SmartAction::ACTION_CALL_RANDOM_TIMED_ACTIONLIST.' AND (`action_param1` = '.$eog.' OR `action_param2` = '.$eog.' OR `action_param3` = '.$eog.' OR `action_param4` = '.$eog.' OR `action_param5` = '.$eog.')'; + $q[] = [DB::AND, array( + ['`action_type` = %i', SmartAction::ACTION_CALL_RANDOM_TIMED_ACTIONLIST], + ['`action_param1` = %i', $eog], + ['`action_param2` = %i', $eog], + ['`action_param3` = %i', $eog], + ['`action_param4` = %i', $eog], + ['`action_param5` = %i', $eog] + )]; // SmartAction::ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST - $q[] = '`action_type` = '.SmartAction::ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST.' AND `action_param1` <= '.$eog.' AND `action_param2` >= '.$eog; + $q[] = [DB::AND, array( + ['`action_type` = %i', SmartAction::ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST], + ['%i BETWEEN `action_param1` AND `action_param2`', $eog] + )]; } - if ($_ = DB::World()->select(sprintf('SELECT `source_type` AS "0", `entryOrGUID` AS "1" FROM smart_scripts WHERE ((%s)){ AND `source_type` IN (?a)}', $q ? implode(') OR (', $q) : '0'), $talFilter ?: DBSIMPLE_SKIP)) + if ($talFilter) + $where[] = ['`source_type` IN %in', $talFilter]; + if ($q) + $where[] = [DB::OR, $q]; + + if ($_ = DB::World()->selectAssoc('SELECT `source_type` AS "0", `entryOrGUID` AS "1" FROM smart_scripts WHERE %and', $where ?: [0])) $smartS = array_merge($smartS, $_); } @@ -442,18 +466,18 @@ class SmartAI { $smartS = array_diff_key($smartS, $smartG); - $q = []; + $where = []; foreach ($smartG as [$st, $eog]) { if ($st == self::SRC_TYPE_CREATURE) - $q[] = '`type` = '.Type::NPC.' AND `guid` = '.-$eog; + $where[] = [DB::AND, [['`type` = %i', Type::NPC], ['`guid` = %i', -$eog]]]; else if ($st == self::SRC_TYPE_OBJECT) - $q[] = '`type` = '.Type::OBJECT.' AND `guid` = '.-$eog; + $where[] = [DB::AND, [['`type` = %i', Type::OBJECT], ['`guid` = %i', -$eog]]]; } - if ($q) + if ($where) { - $owner = DB::Aowow()->select(sprintf('SELECT `type`, `typeId` FROM ?_spawns WHERE (%s)', implode(') OR (', $q))); + $owner = DB::Aowow()->selectAssoc('SELECT `type`, `typeId` FROM ::spawns WHERE %or', $where); foreach ($owner as $o) $result[$o['type']][] = $o['typeId']; } @@ -492,15 +516,15 @@ class SmartAI if ($srcType == self::SRC_TYPE_CREATURE || $srcType == self::SRC_TYPE_OBJECT) { $st = $srcType == self::SRC_TYPE_CREATURE ? SUMMONER_TYPE_CREATURE : SUMMONER_TYPE_GAMEOBJECT; - if ($csg = DB::World()->selectCol('SELECT `entry` FROM creature_summon_groups WHERE `summonerType` = ?d AND `summonerId` = ?d', $st, $entry)) + if ($csg = DB::World()->selectCol('SELECT `entry` FROM creature_summon_groups WHERE `summonerType` = %i AND `summonerId` = %i', $st, $entry)) $result = array_merge($result, $csg); } if (!empty($moreInfo[SmartAction::ACTION_SPAWN_SPAWNGROUP])) { $grp = $moreInfo[SmartAction::ACTION_SPAWN_SPAWNGROUP]; - if ($sgs = DB::World()->selectCol('SELECT `spawnId` FROM spawn_group WHERE `spawnType` = ?d AND `groupId` IN (?a)', SUMMONER_TYPE_CREATURE, $grp)) - if ($ids = DB::Aowow()->selectCol('SELECT DISTINCT `typeId` FROM ?_spawns WHERE `type` = ?d AND `guid` IN (?a)', Type::NPC, $sgs)) + if ($sgs = DB::World()->selectCol('SELECT `spawnId` FROM spawn_group WHERE `spawnType` = %i AND `groupId` IN %in', SUMMONER_TYPE_CREATURE, $grp)) + if ($ids = DB::Aowow()->selectCol('SELECT DISTINCT `typeId` FROM ::spawns WHERE `type` = %i AND `guid` IN %in', Type::NPC, $sgs)) $result = array_merge($result, $ids); } @@ -520,8 +544,8 @@ class SmartAI if (!empty($moreInfo[SmartAction::ACTION_SPAWN_SPAWNGROUP])) { $grp = $moreInfo[SmartAction::ACTION_SPAWN_SPAWNGROUP]; - if ($sgs = DB::World()->selectCol('SELECT `spawnId` FROM spawn_group WHERE `spawnType` = ?d AND `groupId` IN (?a)', SUMMONER_TYPE_GAMEOBJECT, $grp)) - if ($ids = DB::Aowow()->selectCol('SELECT DISTINCT `typeId` FROM ?_spawns WHERE `type` = ?d AND `guid` IN (?a)', Type::OBJECT, $sgs)) + if ($sgs = DB::World()->selectCol('SELECT `spawnId` FROM spawn_group WHERE `spawnType` = %i AND `groupId` IN %in', SUMMONER_TYPE_GAMEOBJECT, $grp)) + if ($ids = DB::Aowow()->selectCol('SELECT DISTINCT `typeId` FROM ::spawns WHERE `type` = %i AND `guid` IN %in', Type::OBJECT, $sgs)) $result = array_merge($result, $ids); } @@ -557,9 +581,9 @@ class SmartAI if ($entry < 0) // no lookup by GUID return []; - $actionQuery = 'SELECT `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6` FROM smart_scripts WHERE `source_type` = ?d AND `action_type` IN (?a) AND `entryOrGUID` IN (?a)'; + $actionQuery = 'SELECT `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6` FROM smart_scripts WHERE `source_type` = %i AND `action_type` IN %in AND `entryOrGUID` IN %in'; - $smartScripts = DB::World()->select($actionQuery, $sourceType, array_merge(array_keys($lookup), SmartAction::ACTION_ALL_TIMED_ACTION_LISTS), [$entry]); + $smartScripts = DB::World()->selectAssoc($actionQuery, $sourceType, array_merge(array_keys($lookup), SmartAction::ACTION_ALL_TIMED_ACTION_LISTS), [$entry]); $smartResults = []; $smartTALs = []; foreach ($smartScripts as $s) @@ -588,7 +612,7 @@ class SmartAI if ($smartTALs) { - if ($TALActList = DB::World()->select($actionQuery, self::SRC_TYPE_ACTIONLIST, array_keys($lookup), $smartTALs)) + if ($TALActList = DB::World()->selectAssoc($actionQuery, self::SRC_TYPE_ACTIONLIST, array_keys($lookup), $smartTALs)) { foreach ($TALActList as $e) { diff --git a/includes/components/SmartAI/SmartAction.class.php b/includes/components/SmartAI/SmartAction.class.php index 5c23a306..05a354eb 100644 --- a/includes/components/SmartAI/SmartAction.class.php +++ b/includes/components/SmartAI/SmartAction.class.php @@ -416,7 +416,7 @@ class SmartAction case self::ACTION_SET_FACTION: // 2 -> any target if ($this->param[0]) { - $this->param[10] = DB::Aowow()->selectCell('SELECT `factionId` FROM ?_factiontemplate WHERE `id` = ?d', $this->param[0]); + $this->param[10] = DB::Aowow()->selectCell('SELECT `factionId` FROM ::factiontemplate WHERE `id` = %i', $this->param[0]); $this->jsGlobals[Type::FACTION][$this->param[10]] = $this->param[10]; } break; @@ -460,11 +460,11 @@ class SmartAction break; case self::ACTION_ACTIVATE_TAXI: // 52 -> invoker $nodes = DB::Aowow()->selectRow( - 'SELECT tn1.`name_loc0` AS "start_loc0", tn1.name_loc?d AS start_loc?d, tn2.`name_loc0` AS "end_loc0", tn2.name_loc?d AS end_loc?d - FROM ?_taxipath tp - JOIN ?_taxinodes tn1 ON tp.`startNodeId` = tn1.`id` - JOIN ?_taxinodes tn2 ON tp.`endNodeId` = tn2.`id` - WHERE tp.`id` = ?d', + 'SELECT tn1.`name_loc0` AS "start_loc0", tn1.name_loc%i AS start_loc%i, tn2.`name_loc0` AS "end_loc0", tn2.name_loc%i AS end_loc%i + FROM ::taxipath tp + JOIN ::taxinodes tn1 ON tp.`startNodeId` = tn1.`id` + JOIN ::taxinodes tn2 ON tp.`endNodeId` = tn2.`id` + WHERE tp.`id` = %i', Lang::getLocale()->value, Lang::getLocale()->value, Lang::getLocale()->value, Lang::getLocale()->value, $this->param[0] ); $this->param[10] = Util::localizedString($nodes, 'start'); @@ -486,7 +486,7 @@ class SmartAction $this->param[11] = str_pad($pos[0]['posX'] * 10, 3, '0', STR_PAD_LEFT).str_pad($pos[0]['posY'] * 10, 3, '0', STR_PAD_LEFT); } // maybe the mapId is an instane map - else if ($areaId = DB::Aowow()->selectCell('SELECT `id` FROM ?_zones WHERE `mapId` = ?d', $this->param[0])) + else if ($areaId = DB::Aowow()->selectCell('SELECT `id` FROM ::zones WHERE `mapId` = %i', $this->param[0])) $this->param[10] = $areaId; // ...whelp else @@ -507,7 +507,7 @@ class SmartAction if ($this->param[0]) { $slots = $this->param[1] ? Util::mask2bits($this->param[1], 1) : [1, 2, 3]; - $items = DB::World()->selectRow('SELECT `ItemID1`, `ItemID2`, `ItemID3` FROM creature_equip_template WHERE `CreatureID` = ?d AND `ID` = ?d', $this->smartAI->getEntry(), $this->param[0]); + $items = DB::World()->selectRow('SELECT `ItemID1`, `ItemID2`, `ItemID3` FROM creature_equip_template WHERE `CreatureID` = %i AND `ID` = %i', $this->smartAI->getEntry(), $this->param[0]); foreach ($slots as $s) if ($_ = $items['ItemID'.$s]) @@ -536,7 +536,7 @@ class SmartAction $buff = []; if ($this->param[0]) { - $items = DB::World()->selectRow('SELECT `ItemID1`, `ItemID2`, `ItemID3` FROM creature_equip_template WHERE `CreatureID` = ?d AND `ID` = ?d', $this->smartAI->getEntry(), $this->param[0]); + $items = DB::World()->selectRow('SELECT `ItemID1`, `ItemID2`, `ItemID3` FROM creature_equip_template WHERE `CreatureID` = %i AND `ID` = %i', $this->smartAI->getEntry(), $this->param[0]); foreach ($items as $i) { if (!$i) @@ -626,7 +626,7 @@ class SmartAction break; case self::ACTION_SUMMON_CREATURE_GROUP: // 107 -> untargeted if ($this->summons === null) - $this->summons = DB::World()->selectCol('SELECT `groupId` AS ARRAY_KEY, `entry` AS ARRAY_KEY2, COUNT(*) AS "n" FROM creature_summon_groups WHERE `summonerId` = ?d GROUP BY `groupId`, `entry`', $this->smartAI->getEntry()); + $this->summons = DB::World()->selectCol('SELECT `groupId` AS ARRAY_KEY, `entry` AS ARRAY_KEY2, COUNT(*) AS "n" FROM creature_summon_groups WHERE `summonerId` = %i GROUP BY `groupId`, `entry`', $this->smartAI->getEntry()); $buff = []; if (!empty($this->summons[$this->param[0]])) @@ -669,8 +669,8 @@ class SmartAction break; case self::ACTION_SPAWN_SPAWNGROUP: // 131 case self::ACTION_DESPAWN_SPAWNGROUP: // 132 - $this->param[10] = Util::jsEscape(DB::World()->selectCell('SELECT `GroupName` FROM spawn_group_template WHERE `groupId` = ?d', $this->param[0])); - $entities = DB::World()->select('SELECT `spawnType` AS "0", `spawnId` AS "1" FROM spawn_group WHERE `groupId` = ?d', $this->param[0]); + $this->param[10] = Util::jsEscape(DB::World()->selectCell('SELECT `GroupName` FROM spawn_group_template WHERE `groupId` = %i', $this->param[0])); + $entities = DB::World()->selectAssoc('SELECT `spawnType` AS "0", `spawnId` AS "1" FROM spawn_group WHERE `groupId` = %i', $this->param[0]); $n = 5; $buff = []; diff --git a/includes/components/SmartAI/SmartEvent.class.php b/includes/components/SmartAI/SmartEvent.class.php index 1afabb81..5a1f0316 100644 --- a/includes/components/SmartAI/SmartEvent.class.php +++ b/includes/components/SmartAI/SmartEvent.class.php @@ -276,7 +276,7 @@ class SmartEvent case 530: $this->param[10] = Lang::maps('Outland'); break; case 571: $this->param[10] = Lang::maps('Northrend'); break; default: - if ($aId = DB::Aowow()->selectCell('SELECT `id` FROM ?_zones WHERE `mapId` = ?d', $this->param[1])) + if ($aId = DB::Aowow()->selectCell('SELECT `id` FROM ::zones WHERE `mapId` = %i', $this->param[1])) { $this->param[11] = $aId; $this->jsGlobals[Type::ZONE][$aId] = $aId; @@ -290,18 +290,16 @@ class SmartEvent break; case self::EVENT_LINK: // 61 - Used to link together multiple events as a chain of events. - if ($links = DB::World()->selectCol('SELECT `id` FROM smart_scripts WHERE `link` = ?d AND `entryorguid` = ?d AND `source_type` = ?d', $this->id, $this->smartAI->entry, $this->smartAI->srcType)) + if ($links = DB::World()->selectCol('SELECT `id` FROM smart_scripts WHERE `link` = %i AND `entryorguid` = %i AND `source_type` = %i', $this->id, $this->smartAI->entry, $this->smartAI->srcType)) $this->param[10] = Lang::concat($links, Lang::CONCAT_OR, fn($x) => "#[b]".$x."[/b]"); break; case self::EVENT_GOSSIP_SELECT: // 62 - On gossip clicked (gossip_menu_option335). $gmo = DB::World()->selectRow( - 'SELECT gmo.`OptionText` AS "text_loc0" {, gmol.`OptionText` AS text_loc?d } + 'SELECT gmo.`OptionText` AS "text_loc0" %if', Lang::getLocale() != Locale::EN, ', gmol.`OptionText` AS %s', 'text_loc' . Lang::getLocale()->value, '%end FROM gossip_menu_option gmo - LEFT JOIN gossip_menu_option_locale gmol ON gmo.`MenuID` = gmol.`MenuID` AND gmo.`OptionID` = gmol.`OptionID` AND gmol.`Locale` = ?d - WHERE gmo.`MenuId` = ?d AND gmo.`OptionID` = ?d', - Lang::getLocale() != Locale::EN ? Lang::getLocale()->value : DBSIMPLE_SKIP, - Lang::getLocale()->json(), - $this->param[0], $this->param[1] + LEFT JOIN gossip_menu_option_locale gmol ON gmo.`MenuID` = gmol.`MenuID` AND gmo.`OptionID` = gmol.`OptionID` AND gmol.`Locale` = %s + WHERE gmo.`MenuId` = %i AND gmo.`OptionID` = %i', + Lang::getLocale()->json(), $this->param[0], $this->param[1] ); if ($gmo) diff --git a/includes/components/communitycontent.class.php b/includes/components/communitycontent.class.php index 5a2fd7fc..ce7999af 100644 --- a/includes/components/communitycontent.class.php +++ b/includes/components/communitycontent.class.php @@ -31,11 +31,7 @@ class CommunityContent private static array $jsGlobals = []; private static array $subjCache = []; - private static string $coCountQuery = - 'SELECT COUNT(1) - FROM ?_comments c - WHERE c.`replyTo` = ?d AND c.`type` = ?d AND c.`typeId` = ?d AND - ((c.`flags` & ?d) = 0 OR c.`userId` = ?d OR ?d)'; + private static string $coCountQuery = 'SELECT COUNT(1) FROM ::comments c WHERE %and'; private static string $coQuery = 'SELECT c.*, @@ -44,55 +40,54 @@ class CommunityContent a3.`username` AS "deleteUser", a4.`username` AS "responseUser", IFNULL(SUM(ur.`value`), 0) AS "rating", - SUM(IF(ur.`userId` > 0 AND ur.`userId` = ?d, ur.`value`, 0)) AS "userRating", + SUM(IF(ur.`userId` > 0 AND ur.`userId` = %i, ur.`value`, 0)) AS "userRating", IF(r.`id` IS NULL, 0, 1) AS "userReported" - FROM ?_comments c - JOIN ?_account a1 ON c.`userId` = a1.`id` - LEFT JOIN ?_account a2 ON c.`editUserId` = a2.`id` - LEFT JOIN ?_account a3 ON c.`deleteUserId` = a3.`id` - LEFT JOIN ?_account a4 ON c.`responseUserId` = a4.`id` - LEFT JOIN ?_user_ratings ur ON c.`id` = ur.`entry` AND ur.`type` = ?d - LEFT JOIN ?_reports r ON r.`subject` = c.`id` AND r.`mode` = ?d AND r.`userId` = ?d - WHERE c.`replyTo` = ?d AND c.`type` = ?d AND c.`typeId` = ?d AND - ((c.`flags` & ?d) = 0 OR c.`userId` = ?d OR ?d) + FROM ::comments c + JOIN ::account a1 ON c.`userId` = a1.`id` + LEFT JOIN ::account a2 ON c.`editUserId` = a2.`id` + LEFT JOIN ::account a3 ON c.`deleteUserId` = a3.`id` + LEFT JOIN ::account a4 ON c.`responseUserId` = a4.`id` + LEFT JOIN ::user_ratings ur ON c.`id` = ur.`entry` AND ur.`type` = %i + LEFT JOIN ::reports r ON r.`subject` = c.`id` AND r.`mode` = %i AND r.`userId` = %i + WHERE %and GROUP BY c.`id` - ORDER BY c.`date` ASC'; + ORDER BY c.`date` ASC + %lmt'; private static string $ssQuery = - 'SELECT s.`id` AS ARRAY_KEY, s.`id`, a.`username` AS "user", s.`date`, s.`width`, s.`height`, s.`caption`, IF(s.`status` & ?d, 1, 0) AS "sticky", s.`type`, s.`typeId` - FROM ?_screenshots s - LEFT JOIN ?_account a ON s.`userIdOwner` = a.`id` - WHERE { s.`userIdOwner` = ?d AND }{ s.`type` = ? AND }{ s.`typeId` = ? AND } s.`status` & ?d AND (s.`status` & ?d) = 0 - { ORDER BY ?# DESC } - { LIMIT ?d }'; + 'SELECT s.`id` AS ARRAY_KEY, s.`id`, a.`username` AS "user", s.`date`, s.`width`, s.`height`, s.`caption`, IF(s.`status` & %i, 1, 0) AS "sticky", s.`type`, s.`typeId` + FROM ::screenshots s + LEFT JOIN ::account a ON s.`userIdOwner` = a.`id` + WHERE %and + ORDER BY `date` DESC + %lmt'; private static string $viQuery = - 'SELECT v.`id` AS ARRAY_KEY, v.`id`, a.`username` AS "user", v.`date`, v.`videoId`, v.`caption`, IF(v.`status` & ?d, 1, 0) AS "sticky", v.`type`, v.`typeId` - FROM ?_videos v - LEFT JOIN ?_account a ON v.`userIdOwner` = a.`id` - WHERE { v.`userIdOwner` = ?d AND }{ v.`type` = ? AND }{ v.`typeId` = ? AND } v.`status` & ?d AND (v.`status` & ?d) = 0 - { ORDER BY ?# ASC } - { LIMIT ?d }'; + 'SELECT v.`id` AS ARRAY_KEY, v.`id`, a.`username` AS "user", v.`date`, v.`videoId`, v.`caption`, IF(v.`status` & %i, 1, 0) AS "sticky", v.`type`, v.`typeId` + FROM ::videos v + LEFT JOIN ::account a ON v.`userIdOwner` = a.`id` + WHERE %and + ORDER BY %by + %lmt'; private static string $previewQuery = 'SELECT c.`id`, c.`body` AS "preview", c.`date`, c.`replyTo` AS "commentid", - IF(c.`flags` & ?d, 1, 0) AS "deleted", + IF(c.`flags` & %i, 1, 0) AS "deleted", IF(c.`type` <> 0, c.`type`, c2.`type`) AS "type", IF(c.`typeId` <> 0, c.`typeId`, c2.`typeId`) AS "typeId", IFNULL(SUM(ur.`value`), 0) AS "rating", a.`username` AS "user" - FROM ?_comments c - JOIN ?_account a ON c.`userId` = a.`id` - LEFT JOIN ?_user_ratings ur ON ur.`entry` = c.`id` AND ur.`userId` <> 0 AND ur.`type` = 1 - LEFT JOIN ?_comments c2 ON c.`replyTo` = c2.`id` - WHERE %s - ((c.`flags` & ?d) = 0 OR c.`userId` = ?d OR ?d) + FROM ::comments c + JOIN ::account a ON c.`userId` = a.`id` + LEFT JOIN ::user_ratings ur ON ur.`entry` = c.`id` AND ur.`userId` <> 0 AND ur.`type` = 1 + LEFT JOIN ::comments c2 ON c.`replyTo` = c2.`id` + WHERE %and GROUP BY c.`id` ORDER BY c.`date` DESC - { LIMIT ?d }'; + %lmt'; private static function addSubject(int $type, int $typeId) : void { @@ -117,7 +112,7 @@ class CommunityContent } } - public static function getCommentPreviews(array $opt = [], ?int &$nFound = 0, bool $dateFmt = true, int $resultLimit = 0) : array + public static function getCommentPreviews(array $opt = [], ?int &$nFound = 0, bool $dateFmt = true, int $resultLimit = PHP_INT_MAX) : array { /* purged:0, <- doesnt seem to be used anymore @@ -127,41 +122,28 @@ class CommunityContent // add default values $opt += ['user' => 0, 'unrated' => 0, 'comments' => 0, 'replies' => 0, 'flags' => 0]; - $w = []; + $where = []; + if (!User::isInGroup(U_GROUP_COMMENTS_MODERATOR)) + $where[] = [DB::OR, [['(c.`flags` & %i) = 0', CC_FLAG_DELETED], ['c.`userId` = %i', User::$id]]]; if ($opt['user']) - $w[] = sprintf('c.`userId` = %d AND', $opt['user']); + $where[] = ['c.`userId` = %i', $opt['user']]; if ($opt['unrated']) - $w[] = 'ur.`entry` IS NULL AND'; + $where[] = ['ur.`entry` IS %sN', null]; if ($opt['flags']) - $w[] = sprintf('(c.`flags` & %d) > 0 AND', $opt['flags']); + $where[] = ['(c.`flags` & %i) > 0', $opt['flags']]; if ($opt['comments'] && !$opt['replies']) - $w[] = 'c.`replyTo` = 0 AND'; + $where[] = ['c.`replyTo` = 0']; else if (!$opt['comments'] && $opt['replies']) - $w[] = 'c.`replyTo` <> 0 AND'; + $where[] = ['c.`replyTo` <> 0']; // else // pick both and no extra constraint needed for that - $query = sprintf(self::$previewQuery, implode(' ', $w)); - - $comments = DB::Aowow()->select( - $query, - CC_FLAG_DELETED, - CC_FLAG_DELETED, - User::$id, - User::isInGroup(U_GROUP_COMMENTS_MODERATOR), - $resultLimit ?: DBSIMPLE_SKIP - ); + $comments = DB::Aowow()->selectAssoc(self::$previewQuery, CC_FLAG_DELETED, $where, $resultLimit); if (!$comments) return []; - $nFound = DB::Aowow()->selectCell( - substr_replace($query, 'SELECT COUNT(*) ', 0, strpos($query, 'FROM')), - CC_FLAG_DELETED, - User::$id, - User::isInGroup(U_GROUP_COMMENTS_MODERATOR), - DBSIMPLE_SKIP - ); + $nFound = DB::Aowow()->selectCell(substr_replace(self::$previewQuery, 'SELECT COUNT(*) ', 0, strpos(self::$previewQuery, 'FROM')), $where, PHP_INT_MAX); foreach ($comments as $c) self::addSubject($c['type'], $c['typeId']); @@ -196,15 +178,22 @@ class CommunityContent return array_values($comments); } - public static function getCommentReplies(int $commentId, int $limit = 0, ?int &$nFound = 0) : array + public static function getCommentReplies(int $commentId, int $resultLimit = PHP_INT_MAX, ?int &$nFound = 0) : array { - $replies = []; - $query = $limit > 0 ? self::$coQuery.' LIMIT '.$limit : self::$coQuery; + $where = array( + ['c.`replyTo` = %i', $commentId], + ['c.`type` = %i', 0], + ['c.`typeId` = %i', 0] + ); + + if (!User::isInGroup(U_GROUP_COMMENTS_MODERATOR)) + $where[] = [DB::OR, [['(c.`flags` & %i) = 0', CC_FLAG_DELETED], ['c.`userId` = %i', User::$id]]]; // get replies - if ($results = DB::Aowow()->select($query, User::$id, RATING_COMMENT, Report::MODE_COMMENT, User::$id, $commentId, 0, 0, CC_FLAG_DELETED, User::$id, User::isInGroup(U_GROUP_COMMENTS_MODERATOR))) + $replies = []; + if ($results = DB::Aowow()->selectAssoc(self::$coQuery, User::$id, RATING_COMMENT, Report::MODE_COMMENT, User::$id, $where, $resultLimit)) { - $nFound = DB::Aowow()->selectCell(self::$coCountQuery, $commentId, 0, 0, CC_FLAG_DELETED, User::$id, User::isInGroup(U_GROUP_COMMENTS_MODERATOR)); + $nFound = DB::Aowow()->selectCell(self::$coCountQuery, $where); foreach ($results as $r) { @@ -239,7 +228,17 @@ class CommunityContent public static function getComments(int $type, int $typeId) : array { - $results = DB::Aowow()->query(self::$coQuery, User::$id, RATING_COMMENT, Report::MODE_COMMENT, User::$id, 0, $type, $typeId, CC_FLAG_DELETED, User::$id, (int)User::isInGroup(U_GROUP_COMMENTS_MODERATOR)); + $where = array( + ['c.`replyTo` = %i', 0], + ['c.`type` = %i', $type], + ['c.`typeId` = %i', $typeId] + ); + + if (!User::isInGroup(U_GROUP_COMMENTS_MODERATOR)) + $where[] = [DB::OR, [['(c.`flags` & %i) = 0', CC_FLAG_DELETED], ['c.`userId` = %i', User::$id]]]; + + // get replies + $results = DB::Aowow()->selectAssoc(self::$coQuery, User::$id, RATING_COMMENT, Report::MODE_COMMENT, User::$id, $where, PHP_INT_MAX); $comments = []; // additional informations @@ -295,32 +294,27 @@ class CommunityContent return $comments; } - public static function getVideos(int $typeOrUser = 0, int $typeId = 0, ?int &$nFound = 0, bool $dateFmt = true, int $resultLimit = 0) : array + public static function getVideos(int $typeOrUser = 0, int $typeId = 0, ?int &$nFound = 0, bool $dateFmt = true, int $resultLimit = PHP_INT_MAX) : array { - $videos = DB::Aowow()->select(self::$viQuery, - CC_FLAG_STICKY, - $typeOrUser < 0 ? -$typeOrUser : DBSIMPLE_SKIP, - $typeOrUser > 0 ? $typeOrUser : DBSIMPLE_SKIP, - $typeOrUser > 0 ? $typeId : DBSIMPLE_SKIP, - CC_FLAG_APPROVED, - CC_FLAG_DELETED, - !$typeOrUser ? 'date' : 'pos', - $resultLimit ?: DBSIMPLE_SKIP + $where = array( + ['v.`status` & %i', CC_FLAG_APPROVED], + ['(v.`status` & %i) = 0', CC_FLAG_DELETED] + ); + if ($typeOrUser < 0) + $where[] = ['v.`userIdOwner` = %i', -$typeOrUser]; + if ($typeOrUser > 0) + { + $where[] = ['v.`type` = %i', $typeOrUser]; + $where[] = ['v.`typeId` = %i', $typeId]; + } + + $videos = DB::Aowow()->selectAssoc(self::$viQuery, CC_FLAG_STICKY, $where, $typeOrUser ? ['date' => false] : ['pos' => true], $resultLimit); if (!$videos) return []; - $nFound = DB::Aowow()->selectCell( - substr_replace(self::$viQuery, 'SELECT COUNT(*) ', 0, strpos(self::$viQuery, 'FROM')), - $typeOrUser < 0 ? -$typeOrUser : DBSIMPLE_SKIP, - $typeOrUser > 0 ? $typeOrUser : DBSIMPLE_SKIP, - $typeOrUser > 0 ? $typeId : DBSIMPLE_SKIP, - CC_FLAG_APPROVED, - CC_FLAG_DELETED, - !$typeOrUser ? 'date' : 'pos', - DBSIMPLE_SKIP - ); + $nFound = DB::Aowow()->selectCell(substr_replace(self::$viQuery, 'SELECT COUNT(*) ', 0, strpos(self::$viQuery, 'FROM')), $where, $typeOrUser ? ['date' => false] : ['pos' => true], PHP_INT_MAX); if ($typeOrUser <= 0) // not for search by type/typeId { @@ -354,32 +348,31 @@ class CommunityContent return array_values($videos); } - public static function getScreenshots(int $typeOrUser = 0, int $typeId = 0, ?int &$nFound = 0, bool $dateFmt = true, int $resultLimit = 0) : array + public static function getScreenshots(int $typeOrUser = 0, int $typeId = 0, ?int &$nFound = 0, bool $dateFmt = true, int $resultLimit = PHP_INT_MAX) : array { - $screenshots = DB::Aowow()->select(self::$ssQuery, + $where = array( + ['s.`status` & %i', CC_FLAG_APPROVED], + ['(s.`status` & %i) = 0', CC_FLAG_DELETED] + + ); + if ($typeOrUser < 0) + $where[] = ['s.`userIdOwner` = %i', -$typeOrUser]; + if ($typeOrUser > 0) + { + $where[] = ['s.`type` = %i', $typeOrUser]; + $where[] = ['s.`typeId` = %i', $typeId]; + } + + $screenshots = DB::Aowow()->selectAssoc(self::$ssQuery, CC_FLAG_STICKY, - $typeOrUser < 0 ? -$typeOrUser : DBSIMPLE_SKIP, - $typeOrUser > 0 ? $typeOrUser : DBSIMPLE_SKIP, - $typeOrUser > 0 ? $typeId : DBSIMPLE_SKIP, - CC_FLAG_APPROVED, - CC_FLAG_DELETED, - !$typeOrUser ? 'date' : DBSIMPLE_SKIP, - $resultLimit ?: DBSIMPLE_SKIP + $where, + $resultLimit ); if (!$screenshots) return []; - $nFound = DB::Aowow()->selectCell( - substr_replace(self::$ssQuery, 'SELECT COUNT(*) ', 0, strpos(self::$ssQuery, 'FROM')), - $typeOrUser < 0 ? -$typeOrUser : DBSIMPLE_SKIP, - $typeOrUser > 0 ? $typeOrUser : DBSIMPLE_SKIP, - $typeOrUser > 0 ? $typeId : DBSIMPLE_SKIP, - CC_FLAG_APPROVED, - CC_FLAG_DELETED, - !$typeOrUser ? 'date' : DBSIMPLE_SKIP, - DBSIMPLE_SKIP - ); + $nFound = DB::Aowow()->selectCell(substr_replace(self::$ssQuery, 'SELECT COUNT(*) ', 0, strpos(self::$ssQuery, 'FROM')), $where, PHP_INT_MAX); if ($typeOrUser <= 0) // not for search by type/typeId { diff --git a/includes/components/dbtypelist.class.php b/includes/components/dbtypelist.class.php index 6e34833f..43dc976b 100644 --- a/includes/components/dbtypelist.class.php +++ b/includes/components/dbtypelist.class.php @@ -17,6 +17,7 @@ abstract class DBTypeList protected array $queryOpts = []; private array $itrStack = []; + private array $prefixes = []; public static int $type; public static int $contribute = CONTRIBUTE_ANY; @@ -47,14 +48,14 @@ abstract class DBTypeList * ['id', 45], * ['name', 'test%', '!'], * [ - * 'AND', + * DB::AND, * ['flags', 0xFF, '&'], * ['flags2', 0xF, '&'], * ] * [['mask', 0x3, '&'], 0], * ['nameField', ['+contains*', '-excludes'], 'MATCH], * ['joinedTbl.field', NULL] // NULL must be explicitly specified "['joinedTbl.field']" would be skipped as erroneous definition (only really usefull when left-joining) - * 'OR', + * DB::OR, * 5 * ) * results in @@ -63,7 +64,7 @@ abstract class DBTypeList public function __construct(array $conditions = [], array $miscData = []) { $where = []; - $linking = ' AND '; + $linking = DB::AND; $limit = 0; $calcTotal = false; @@ -72,11 +73,10 @@ abstract class DBTypeList if (!$this->queryBase || $conditions === null) return; - $prefixes = []; - if (preg_match('/FROM \??[\w\_]+( AS)?\s?`?(\w+)`?$/i', $this->queryBase, $match)) - $prefixes['base'] = $match[2]; + if (preg_match('/FROM (?:::)?[\w\_]+( AS)?\s?`?(\w+)`?$/i', $this->queryBase, $match)) + $this->prefixes['base'] = $match[2]; else - $prefixes['base'] = ''; + $this->prefixes['base'] = ''; if (!empty($miscData['extraOpts'])) $this->extendQueryOpts($miscData['extraOpts']); @@ -84,138 +84,6 @@ abstract class DBTypeList if (!empty($miscData['calcTotal'])) $calcTotal = true; - $resolveCondition = function (array $c, string $supLink) use (&$resolveCondition, &$prefixes) : ?string - { - $subLink = ''; - - if (!$c) - return null; - - foreach ($c as $foo) - { - if ($foo === 'AND') - $subLink = ' AND '; - else if ($foo === 'OR') // nessi-bug: if (0 == 'OR') was true once... w/e - $subLink = ' OR '; - } - - // need to manually set link for subgroups to be recognized as condition set - if ($subLink) - { - $sql = []; - - foreach ($c as $foo) - if (is_array($foo)) - if ($x = $resolveCondition($foo, $supLink)) - $sql[] = $x; - - return $sql ? '('.implode($subLink, $sql).')' : null; - } - else - { - if ($c[0] == '1') - return '1'; - else if ($c[0] == '0') - return '(0)'; // trick if ($x = 0) into true... - else if (is_array($c[0]) && isset($c[1])) - $field = $resolveCondition($c[0], $supLink); - else if ($c[0]) - { - $setPrefix = function(mixed $f) use(&$prefixes) : ?string - { - if (is_array($f)) - $f = $f[0]; - - // numeric allows for formulas e.g. (1 < 3) - if (Util::checkNumeric($f)) - return $f; - - // skip condition if fieldName contains illegal chars - if (preg_match('/[^\d\w\.\_]/i', $f)) - return null; - - $f = explode('.', $f); - - switch (count($f)) - { - case 2: - if (!in_array($f[0], $prefixes)) - { - // choose table to join or return null if prefix does not exist - if (!in_array($f[0], array_keys($this->queryOpts))) - return null; - - $prefixes[] = $f[0]; - } - - return '`'.$f[0].'`.`'.$f[1].'`'; - case 1: - return '`'.$prefixes['base'].'`.`'.$f[0].'`'; - default: - return null; - } - }; - - // basic formulas - if (preg_match('/^\([\s\+\-\*\/\w\(\)\.]+\)$/i', strtr($c[0], ['`' => '', '´' => '', '--' => '']))) - $field = preg_replace_callback('/[\w\]*\.?[\w]+/i', $setPrefix, $c[0]); - else - $field = $setPrefix($c[0]); - - if (!$field) - return null; - } - else - return null; - - $c[2] ??= ''; - - if (is_array($c[1]) && !empty($c[1])) - { - if ($c[2] === 'MATCH') - return 'MATCH('.$field.') AGAINST(\''.implode(' ', $c[1]).'\' IN BOOLEAN MODE)'; - - array_walk($c[1], fn(&$x) => $x = Util::checkNumeric($x) ? $x : DB::Aowow()->escape($x)); - - $op = $c[2] == '!' ? 'NOT IN' : 'IN'; - $val = '('.implode(', ', $c[1]).')'; - } - else if (Util::checkNumeric($c[1])) // Note: should this be a NUM_REQ_* check? - { - $val = $c[1]; - $op = $c[2] == '!' ? '<>' : ($c[2] ?: '='); - } - else if (is_string($c[1])) - { - $val = mysqli_real_escape_string(DB::Aowow()->link, $c[1]); - if ($c[2] == 'LIKE') - { - $op = 'LIKE'; - $val = '"%'.$val.'%"'; - } - else if ($c[2] == 'NOT LIKE') - { - $op = 'NOT LIKE'; - $val = '"%'.$val.'%"'; - } - else - { - $op = $c[2] == '!' ? '<>' : '='; - $val = '"'.$val.'"'; - } - } - else if (count($c) > 1 && $c[1] === null) // specifficly check for NULL - { - $op = $c[2] == '!' ? 'IS NOT' : 'IS'; - $val = 'NULL'; - } - else // null for example - return null; - - return '('.$field.' '.$op.' '.$val.')'; - } - }; - foreach ($conditions as $i => $c) { switch (getType($c)) @@ -226,27 +94,29 @@ abstract class DBTypeList case 'integer': if (is_numeric($c)) $limit = max(0, (int)$c); - else - $linking = $c == 'AND' ? ' AND ' : ' OR '; + else if ($c === DB::AND) + $linking = DB::AND; + else if ($c === DB::OR) + $linking = DB::OR; default: unset($conditions[$i]); } } foreach ($conditions as $c) - if ($x = $resolveCondition($c, $linking)) + if ($x = $this->resolveCondition($c, $linking)) $where[] = $x; // optional query parts may require other optional parts to work - foreach ($prefixes as $pre) + foreach ($this->prefixes as $pre) if (isset($this->queryOpts[$pre][0])) foreach ($this->queryOpts[$pre][0] as $req) - if (!in_array($req, $prefixes)) - $prefixes[] = $req; + if (!in_array($req, $this->prefixes)) + $this->prefixes[] = $req; // remove optional query parts, that are not required foreach ($this->queryOpts as $k => $arr) - if (!in_array($k, $prefixes)) + if (!in_array($k, $this->prefixes)) unset($this->queryOpts[$k]); // prepare usage of guids if using multiple realms (which have non-zoro indizes) @@ -264,7 +134,7 @@ abstract class DBTypeList // append conditions if ($where) - $this->queryBase .= ' WHERE ('.implode($linking, $where).')'; + $this->queryBase .= ' WHERE '.$linking; // append grouping if ($g = array_filter(array_column($this->queryOpts, 'g'))) @@ -287,14 +157,15 @@ abstract class DBTypeList $this->queryBase .= ' LIMIT '.$limit; // execute query (finally) - $rows = []; // this is purely because of multiple realms per server foreach ($this->dbNames as $dbIdx => $n) { - $query = str_replace('DB_IDX', $dbIdx, $this->queryBase); - if ($rows = DB::{$n}($dbIdx)->select($query)) + try // does not go through the compatibility layer as we need to be able to fetch individual rows here { - if ($calcTotal) + $query = str_replace('DB_IDX', $dbIdx, $this->queryBase); + $result = DB::{$n}($dbIdx)->query($query, $where); + + if ($calcTotal && $result->getRowCount()) { // hackfix the inner items query to not contain duplicate column names // yes i know the real solution would be to not have items and item_stats share column names @@ -302,17 +173,21 @@ abstract class DBTypeList if (get_class($this) == ItemList::class) $totalQuery = str_replace([', `is`.*', ', i.`id` AS "id"'], '', $totalQuery); - $this->matches += DB::{$n}($dbIdx)->selectCell('SELECT COUNT(*) FROM ('.$totalQuery.') x'); + $this->matches += DB::{$n}($dbIdx)->selectCell('SELECT COUNT(*) FROM ('.$totalQuery.') x', $where); } - foreach ($rows as $id => $row) + foreach ($result->getIterator() as $row) { - if (isset($this->templates[$id])) - trigger_error('GUID for List already in use #'.$id.'. Additional occurrence omitted!', E_USER_ERROR); + // just .. roll with the unparsed, deprecated ARRAY_KEY, hmk? + if (isset($this->templates[$row['ARRAY_KEY']])) + trigger_error('GUID for List already in use #'.$row['ARRAY_KEY'].'. Additional occurrence omitted!', E_USER_ERROR); else - $this->templates[$id] = $row; + $this->templates[$row['ARRAY_KEY']] = (array)$row; } + + $result->free(); } + catch (\Exception $e) {} // logged via \Dibi\Event in DB::errorLogger } if (!$this->templates) @@ -325,6 +200,107 @@ abstract class DBTypeList $this->error = false; } + private function resolveCondition(array $c, string $supLink) : ?array + { + if (!$c) + return null; + + // i am recursive subcondition + if ($subLink = array_find($c, fn($x) => $x === DB::AND || $x === DB::OR)) + { + $sql = []; + + foreach ($c as $foo) + if (is_array($foo)) + if ($x = $this->resolveCondition($foo, $supLink)) + $sql[] = $x; + + return $sql ? [$subLink, $sql] : null; + } + + [$expOrField, $value, $op] = array_pad($c, 3, null); + + if (is_numeric($expOrField)) + return [$expOrField ? 1 : 0]; // [1] / [0] + if (!$expOrField) // '', null, [] + return null; + + $literal = false; + + if (is_array($expOrField)) + $field = $this->resolveCondition($expOrField, $supLink); + else + { + // basic formulas ex: [((minGold + maxGold) / 2), 0, '>'] + if (preg_match('/^\([\s\+\-\*\/\w\(\)\.]+\)$/i', strtr($expOrField, ['`' => '', '´' => '', '--' => '']))) + { + $field = preg_replace_callback('/[\w\]*\.?[\w]+/i', $this->setColPrefix(...), $expOrField); + $literal = true; + } + else + $field = $this->setColPrefix($expOrField); + + if (!$field) + return null; + } + + $neg = $op === '!'; + $expr = match (gettype($value)) + { + 'integer' => ($neg ? '<>' : ($op ?: '=')) . ' %i', + 'double' => ($neg ? '<>' : ($op ?: '=')) . ' %f', + 'string' => ($neg ? '<>' : ($op ?: '=')) . ' %s', + 'NULL' => ($neg ? 'IS NOT' : 'IS') . ' %sN', + 'array' => ($neg ? 'NOT IN' : 'IN') . ' %in', + default => null + }; + + if (!$expr) + return null; + + // [[flags, 0x4, '&'], 0] -> (`flags` & 4) = 0 + if (is_array($field)) // $field is expression + return [...$field, $expr, $value]; + if ($op == 'MATCH' && gettype($value) == 'array') + return ['MATCH(%n)', $field, 'AGAINST(%s IN BOOLEAN MODE)', DB::Aowow()->translate($value)]; + if (($op == 'LIKE' || $op == 'NOT LIKE') && gettype($value) == 'string') + return ['%n', $field, $op, '%~like~', $value]; + + return [$literal ? '%SQL' : '%n', $field, $expr, $value]; + } + + private function setColPrefix(mixed $colName) : ?string + { + if (is_array($colName)) + $colName = $colName[0]; + + // numeric allows for formulas e.g. (1 < 3) + if (Util::checkNumeric($colName)) + return $colName; + + // skip condition if fieldName contains illegal chars + if (preg_match('/[^\d\w\.\_]/i', $colName)) + return null; + + [$prefix, $col, $err] = array_pad(explode('.', $colName), 3, null); + + if ($err) // more than one period + return null; + if (!$col) // prefix not set, so everything is shifted to the left :/ + return $this->prefixes['base'].'.'.$prefix; + + if (!in_array($prefix, $this->prefixes)) + { + // choose table to join or return null if prefix does not exist + if (!in_array($prefix, array_keys($this->queryOpts))) + return null; + + $this->prefixes[] = $prefix; + } + + return $prefix.'.'.$col; + } + /** * iterate over fetched templates * @@ -416,11 +392,8 @@ abstract class DBTypeList public function getRandomId() : int { - // ORDER BY RAND() is not optimal, so if anyone has an alternative idea.. - $where = User::isInGroup(U_GROUP_EMPLOYEE) ? ' WHERE (`cuFlags` & '.CUSTOM_EXCLUDE_FOR_LISTVIEW.') = 0' : ''; - - if (preg_match('/SELECT .*? FROM (\?\_[\w_-]+) /i', $this->queryBase, $m)) - return DB::Aowow()->selectCell(sprintf('SELECT `id` FROM %s%s ORDER BY RAND() ASC LIMIT 1', $m[1], $where)); + if (preg_match('/SELECT .*? FROM (::[\w_-]+) /i', $this->queryBase, $m)) + return DB::Aowow()->selectCell('SELECT `id` FROM %n WHERE (`cuFlags` & %i) = 0 ORDER BY RAND() ASC LIMIT 1', $m[1], User::isInGroup(U_GROUP_EMPLOYEE) ? 0 : CUSTOM_EXCLUDE_FOR_LISTVIEW) ?: 0; return 0; } @@ -482,7 +455,7 @@ abstract class DBTypeList public static function getName(int $id) : ?LocString { - if ($n = DB::Aowow()->SelectRow('SELECT `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8` FROM ?# WHERE `id` = ?d', static::$dataTable, $id)) + if ($n = DB::Aowow()->SelectRow('SELECT `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8` FROM %n WHERE `id` = %i', static::$dataTable, $id)) return new LocString($n); return null; } @@ -636,10 +609,10 @@ trait spawnHelper $this->spawnResult[SPAWNINFO_SHORT] = new \StdClass; // first get zone/floor with the most spawns - if ($res = DB::Aowow()->selectRow('SELECT `areaId`, `floor` FROM ?_spawns WHERE `type` = ?d AND `typeId` = ?d AND `posX` > 0 AND `posY` > 0 GROUP BY `areaId`, `floor` ORDER BY COUNT(1) DESC LIMIT 1', self::$type, $this->id)) + if ($res = DB::Aowow()->selectRow('SELECT `areaId`, `floor` FROM ::spawns WHERE `type` = %i AND `typeId` = %i AND `posX` > 0 AND `posY` > 0 GROUP BY `areaId`, `floor` ORDER BY COUNT(1) DESC LIMIT 1', self::$type, $this->id)) { // get relevant spawn points - $points = DB::Aowow()->select('SELECT `posX`, `posY` FROM ?_spawns WHERE `type` = ?d AND `typeId` = ?d AND `areaId` = ?d AND `floor` = ?d AND `posX` > 0 AND `posY` > 0', self::$type, $this->id, $res['areaId'], $res['floor']); + $points = DB::Aowow()->selectAssoc('SELECT `posX`, `posY` FROM ::spawns WHERE `type` = %i AND `typeId` = %i AND `areaId` = %i AND `floor` = %i AND `posX` > 0 AND `posY` > 0', self::$type, $this->id, $res['areaId'], $res['floor']); $spawns = []; foreach ($points as $p) $spawns[] = [$p['posX'], $p['posY']]; @@ -656,15 +629,15 @@ trait spawnHelper $wpSum = []; $wpIdx = 0; $worldPos = []; - $spawns = DB::Aowow()->select( - 'SELECT CASE WHEN z.`type` = ?d THEN 1 - WHEN z.`type` = ?d THEN 2 - WHEN z.`type` = ?d THEN 2 + $spawns = DB::Aowow()->selectAssoc( + 'SELECT CASE WHEN z.`type` = %i THEN 1 + WHEN z.`type` = %i THEN 2 + WHEN z.`type` = %i THEN 2 ELSE 0 END AS "mapType", s.* - FROM ?_spawns s - JOIN ?_zones z ON s.areaId = z.id - WHERE s.`type` = ?d AND s.`typeId` IN (?a) AND s.`posX` > 0 AND s.`posY` > 0', + FROM ::spawns s + JOIN ::zones z ON s.areaId = z.id + WHERE s.`type` = %i AND s.`typeId` IN %in AND s.`posX` > 0 AND s.`posY` > 0', MAP_TYPE_DUNGEON_HC, MAP_TYPE_MMODE_RAID, MAP_TYPE_MMODE_RAID_HC, self::$type, $this->getFoundIDs() ) ?: []; @@ -681,7 +654,7 @@ trait spawnHelper // we will get a nice clusterfuck of dots if we do this for more GUIDs, than we have colors though if (!$skipWPs && count($spawns) < 6 && $s['type'] == Type::NPC) { - if ($wPoints = DB::Aowow()->select('SELECT * FROM ?_creature_waypoints WHERE creatureOrPath = ?d AND floor = ?d', $s['pathId'] ? -$s['pathId'] : $this->id, $s['floor'])) + if ($wPoints = DB::Aowow()->selectAssoc('SELECT * FROM ::creature_waypoints WHERE creatureOrPath = %i AND floor = %i', $s['pathId'] ? -$s['pathId'] : $this->id, $s['floor'])) { foreach ($wPoints as $i => $p) { @@ -816,7 +789,7 @@ trait spawnHelper private function createZoneSpawns() : void // [zoneId1, zoneId2, ..] for locations-column in listview { - $res = DB::Aowow()->selectCol("SELECT `typeId` AS ARRAY_KEY, GROUP_CONCAT(DISTINCT `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId` IN (?a) AND `posX` > 0 AND `posY` > 0 GROUP BY `typeId`", self::$type, $this->getfoundIDs()); + $res = DB::Aowow()->selectCol("SELECT `typeId` AS ARRAY_KEY, GROUP_CONCAT(DISTINCT `areaId`) FROM ::spawns WHERE `type` = %i AND `typeId` IN %in AND `posX` > 0 AND `posY` > 0 GROUP BY `typeId`", self::$type, $this->getfoundIDs()); foreach ($res as &$r) { $r = explode(',', $r); @@ -832,7 +805,7 @@ trait spawnHelper if (self::$type == Type::SOUND) return; - $res = DB::Aowow()->select('SELECT `areaId`, `floor`, `typeId`, `posX`, `posY` FROM ?_spawns WHERE `type` = ?d AND `typeId` IN (?a) AND `posX` > 0 AND `posY` > 0', self::$type, $this->getFoundIDs()); + $res = DB::Aowow()->selectAssoc('SELECT `areaId`, `floor`, `typeId`, `posX`, `posY` FROM ::spawns WHERE `type` = %i AND `typeId` IN %in AND `posX` > 0 AND `posY` > 0', self::$type, $this->getFoundIDs()); $spawns = []; foreach ($res as $data) { diff --git a/includes/components/filter.class.php b/includes/components/filter.class.php index b877ce3e..6cdc439b 100644 --- a/includes/components/filter.class.php +++ b/includes/components/filter.class.php @@ -249,13 +249,13 @@ abstract class Filter if ($filters) // if a filter uses criteria it must have a [ma]tch selector { - $filters[] = empty($this->values['ma']) ? 'AND' : 'OR'; + array_unshift($filters, $this->values['ma'] ? DB::OR : DB::AND); $this->cndSet[] = $filters; } } if ($this->cndSet) - array_unshift($this->cndSet, 'AND'); + array_unshift($this->cndSet, DB::AND); return $this->cndSet; } @@ -659,7 +659,7 @@ abstract class Filter $sub = array_merge($sub, array_map(fn($x) => [$col, $x, $exact ? null : 'NOT LIKE'], $this->exTokens[$field])); if (count($sub) > 1) - array_unshift($sub, 'AND'); + array_unshift($sub, DB::AND); else if ($sub) $sub = $sub[0]; @@ -667,7 +667,7 @@ abstract class Filter $qry[] = $sub; } - return $qry ? ['OR', ...$qry] : []; + return $qry ? [DB::OR, ...$qry] : []; } protected function buildMatchLookup(array $fields, bool $exact = false) : array @@ -686,7 +686,7 @@ abstract class Filter $qry[] = [$col, $tok]; } - return $qry ? ['OR', ...$qry] : []; + return $qry ? [DB::OR, ...$qry] : []; } protected function int2Op(mixed &$op) : bool diff --git a/includes/components/guidemgr.class.php b/includes/components/guidemgr.class.php index a5c5ea6c..61a41b5b 100644 --- a/includes/components/guidemgr.class.php +++ b/includes/components/guidemgr.class.php @@ -45,7 +45,7 @@ class GuideMgr self::$ratingsStore = array_fill_keys($guideIds, ['nvotes' => 0, 'rating' => -1]); - $ratings = DB::Aowow()->select('SELECT `entry` AS ARRAY_KEY, IFNULL(SUM(`value`), 0) AS "0", IFNULL(COUNT(*), 0) AS "1", IFNULL(MAX(IF(`userId` = ?d, `value`, 0)), 0) AS "2" FROM ?_user_ratings WHERE `type` = ?d AND `entry` IN (?a) GROUP BY `entry`', User::$id, RATING_GUIDE, $guideIds); + $ratings = DB::Aowow()->selectAssoc('SELECT `entry` AS ARRAY_KEY, IFNULL(SUM(`value`), 0) AS "0", IFNULL(COUNT(*), 0) AS "1", IFNULL(MAX(IF(`userId` = %i, `value`, 0)), 0) AS "2" FROM ::user_ratings WHERE `type` = %i AND `entry` IN %in GROUP BY `entry`', User::$id, RATING_GUIDE, $guideIds); foreach ($ratings as $id => [$total, $count, $self]) { self::$ratingsStore[$id]['nvotes'] = (int)$count; diff --git a/includes/components/profiler.class.php b/includes/components/profiler.class.php index 786e4351..9dc17fea 100644 --- a/includes/components/profiler.class.php +++ b/includes/components/profiler.class.php @@ -18,6 +18,9 @@ class Profiler public const /* int */ FETCH_RESULT_ERR_NO_MEMBERS = 5; public const /* int */ FETCH_RESULT_ERR_INTERNAL = 6; + public const /* int */ COMPLETION_EXCLUDE = 1; + public const /* int */ COMPLETION_INCLUDE = 2; + public const /* array */ REGIONS = array( // see cfg_categories.dbc 'us' => [2, 3, 4, 5], // US (us, oceanic, latin america, americas - tournament) 'kr' => [6, 7], // KR (kr, tournament) @@ -78,7 +81,7 @@ class Profiler return 0; // try, when having filled char-DB at hand - // return DB::Characters()->selectCell('SELECT SUM(a.buyoutprice) / SUM(ii.count) FROM auctionhouse a JOIN item_instance ii ON ii.guid = a.itemguid WHERE ii.itemEntry = ?d', $itemId); + // return DB::Characters()->selectCell('SELECT SUM(a.buyoutprice) / SUM(ii.count) FROM auctionhouse a JOIN item_instance ii ON ii.guid = a.itemguid WHERE ii.itemEntry = %i', $itemId); return 0; } @@ -201,7 +204,7 @@ class Profiler if (!DB::isConnectable(DB_AUTH) || self::$realms) return self::$realms; - $realms = DB::Auth()->select( + $realms = DB::Auth()->selectAssoc( 'SELECT `id` AS ARRAY_KEY, `name`, CASE WHEN `timezone` BETWEEN 2 AND 5 THEN "us" # US, Oceanic, Latin America, Americas-Tournament @@ -212,7 +215,7 @@ class Profiler ELSE "dev" END AS "region", # 1: Dev, 26: Test, 27: Test Tournament, 28: QA, 30: Test2, 31+: misc `allowedSecurityLevel` AS "access" FROM `realmlist` - WHERE `gamebuild` = ?d', + WHERE `gamebuild` = %i', WOW_BUILD ); @@ -260,17 +263,17 @@ class Profiler private static function queueInsert(int $realmId, int $guid, int $type, int $localId) : void { - if ($rData = DB::Aowow()->selectRow('SELECT `requestTime` AS "time", `status` FROM ?_profiler_sync WHERE `realm` = ?d AND `realmGUID` = ?d AND `type` = ?d AND `typeId` = ?d AND `status` <> ?d', $realmId, $guid, $type, $localId, PR_QUEUE_STATUS_WORKING)) + if ($rData = DB::Aowow()->selectRow('SELECT `requestTime` AS "time", `status` FROM ::profiler_sync WHERE `realm` = %i AND `realmGUID` = %i AND `type` = %i AND `typeId` = %i AND `status` <> %i', $realmId, $guid, $type, $localId, PR_QUEUE_STATUS_WORKING)) { // not on already scheduled - recalc time and set status to PR_QUEUE_STATUS_WAITING if ($rData['status'] != PR_QUEUE_STATUS_WAITING) { $newTime = Cfg::get('DEBUG') ? time() : max($rData['time'] + Cfg::get('PROFILER_RESYNC_DELAY'), time()); - DB::Aowow()->query('UPDATE ?_profiler_sync SET `requestTime` = ?d, `status` = ?d, `errorCode` = 0 WHERE `realm` = ?d AND `realmGUID` = ?d AND `type` = ?d AND `typeId` = ?d', $newTime, PR_QUEUE_STATUS_WAITING, $realmId, $guid, $type, $localId); + DB::Aowow()->qry('UPDATE ::profiler_sync SET `requestTime` = %i, `status` = %i, `errorCode` = 0 WHERE `realm` = %i AND `realmGUID` = %i AND `type` = %i AND `typeId` = %i', $newTime, PR_QUEUE_STATUS_WAITING, $realmId, $guid, $type, $localId); } } else - DB::Aowow()->query('REPLACE INTO ?_profiler_sync (`realm`, `realmGUID`, `type`, `typeId`, `requestTime`, `status`, `errorCode`) VALUES (?d, ?d, ?d, ?d, UNIX_TIMESTAMP(), ?d, 0)', $realmId, $guid, $type, $localId, PR_QUEUE_STATUS_WAITING); + DB::Aowow()->qry('REPLACE INTO ::profiler_sync (`realm`, `realmGUID`, `type`, `typeId`, `requestTime`, `status`, `errorCode`) VALUES (%i, %i, %i, %i, UNIX_TIMESTAMP(), %i, 0)', $realmId, $guid, $type, $localId, PR_QUEUE_STATUS_WAITING); } public static function scheduleResync(int $type, int $realmId, int $guid) : int @@ -280,17 +283,17 @@ class Profiler switch ($type) { case Type::PROFILE: - if ($newId = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $guid)) + if ($newId = DB::Aowow()->selectCell('SELECT `id` FROM ::profiler_profiles WHERE `realm` = %i AND `realmGUID` = %i', $realmId, $guid)) self::queueInsert($realmId, $guid, Type::PROFILE, $newId); break; case Type::GUILD: - if ($newId = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_guild WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $guid)) + if ($newId = DB::Aowow()->selectCell('SELECT `id` FROM ::profiler_guild WHERE `realm` = %i AND `realmGUID` = %i', $realmId, $guid)) self::queueInsert($realmId, $guid, Type::GUILD, $newId); break; case Type::ARENA_TEAM: - if ($newId = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_arena_team WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $guid)) + if ($newId = DB::Aowow()->selectCell('SELECT `id` FROM ::profiler_arena_team WHERE `realm` = %i AND `realmGUID` = %i', $realmId, $guid)) self::queueInsert($realmId, $guid, Type::ARENA_TEAM, $newId); break; @@ -340,10 +343,10 @@ class Profiler else { // error out all profiles with status WORKING, that are older than 60sec - DB::Aowow()->query('UPDATE ?_profiler_sync SET `status` = ?d, `errorCode` = ?d WHERE `status` = ?d AND `requestTime` < ?d', PR_QUEUE_STATUS_ERROR, PR_QUEUE_ERROR_UNK, PR_QUEUE_STATUS_WORKING, time() - MINUTE); + DB::Aowow()->qry('UPDATE ::profiler_sync SET `status` = %i, `errorCode` = %i WHERE `status` = %i AND `requestTime` < %i', PR_QUEUE_STATUS_ERROR, PR_QUEUE_ERROR_UNK, PR_QUEUE_STATUS_WORKING, time() - MINUTE); - $subjectStatus = DB::Aowow()->select('SELECT `typeId` AS ARRAY_KEY, `status`, `realm`, `errorCode`, `requestTime` FROM ?_profiler_sync WHERE `type` = ?d AND `typeId` IN (?a)', $type, $subjectGUIDs); - $queue = DB::Aowow()->selectCol('SELECT CONCAT(`type`, ":", `typeId`) FROM ?_profiler_sync WHERE `status` = ?d AND `requestTime` < UNIX_TIMESTAMP() ORDER BY `requestTime` ASC', PR_QUEUE_STATUS_WAITING); + $subjectStatus = DB::Aowow()->selectAssoc('SELECT `typeId` AS ARRAY_KEY, `status`, `realm`, `errorCode`, `requestTime` FROM ::profiler_sync WHERE `type` = %i AND `typeId` IN %in', $type, $subjectGUIDs); + $queue = DB::Aowow()->selectCol('SELECT CONCAT(`type`, ":", `typeId`) FROM ::profiler_sync WHERE `status` = %i AND `requestTime` < UNIX_TIMESTAMP() ORDER BY `requestTime` ASC', PR_QUEUE_STATUS_WAITING); foreach ($subjectGUIDs as $guid) { if (empty($subjectStatus[$guid])) // whelp, thats some error.. @@ -368,7 +371,7 @@ class Profiler public static function getCharFromRealm(int $realmId, int $charGuid) : int { - $char = DB::Characters($realmId)->selectRow('SELECT c.* FROM characters c WHERE c.`guid` = ?d', $charGuid); + $char = DB::Characters($realmId)->selectRow('SELECT c.* FROM characters c WHERE c.`guid` = %i', $charGuid); if (!$char) return self::FETCH_RESULT_ERR_NOT_FOUND; @@ -376,7 +379,7 @@ class Profiler return self::FETCH_RESULT_ERR_NAME_EMPTY; // reminder: this query should not fail: a placeholder entry is created as soon as a char listview is created or profile detail page is called - $profile = DB::Aowow()->selectRow('SELECT `id`, `lastupdated` FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $char['guid']); + $profile = DB::Aowow()->selectRow('SELECT `id`, `lastupdated` FROM ::profiler_profiles WHERE `realm` = %i AND `realmGUID` = %i', $realmId, $char['guid']); if (!$profile) return self::FETCH_RESULT_ERR_INTERNAL; // well ... it failed @@ -386,7 +389,7 @@ class Profiler if (!$char['online'] && $char['logout_time'] <= $profile['lastupdated']) { - DB::Aowow()->query('UPDATE ?_profiler_profiles SET `lastupdated` = ?d WHERE `id` = ?d', time(), $profileId); + DB::Aowow()->qry('UPDATE ::profiler_profiles SET `lastupdated` = %i WHERE `id` = %i', time(), $profileId); return self::FETCH_RESULT_OK_UNCHANGED; } @@ -412,8 +415,8 @@ class Profiler */ - DB::Aowow()->query('DELETE FROM ?_profiler_items WHERE `id` = ?d', $profileId); - $items = DB::Characters($realmId)->select('SELECT ci.`slot` AS ARRAY_KEY, ii.`itemEntry`, ii.`enchantments`, ii.`randomPropertyId` FROM character_inventory ci JOIN item_instance ii ON ci.`item` = ii.`guid` WHERE ci.`guid` = ?d AND `bag` = 0 AND `slot` BETWEEN 0 AND 18', $char['guid']); + DB::Aowow()->qry('DELETE FROM ::profiler_items WHERE `id` = %i', $profileId); + $items = DB::Characters($realmId)->selectAssoc('SELECT ci.`slot` AS ARRAY_KEY, ii.`itemEntry`, ii.`enchantments`, ii.`randomPropertyId` FROM character_inventory ci JOIN item_instance ii ON ci.`item` = ii.`guid` WHERE ci.`guid` = %i AND `bag` = 0 AND `slot` BETWEEN 0 AND 18', $char['guid']); $gemItems = []; $permEnch = []; @@ -430,7 +433,7 @@ class Profiler if ($gEnch) { - $gi = DB::Aowow()->selectCol('SELECT `gemEnchantmentId` AS ARRAY_KEY, `id` FROM ?_items WHERE `class` = ?d AND `gemEnchantmentId` IN (?a)', ITEM_CLASS_GEM, $gEnch); + $gi = DB::Aowow()->selectCol('SELECT `gemEnchantmentId` AS ARRAY_KEY, `id` FROM ::items WHERE `class` = %i AND `gemEnchantmentId` IN %in', ITEM_CLASS_GEM, $gEnch); foreach ($gEnch as $eId) { if (isset($gemItems[$eId])) @@ -462,7 +465,7 @@ class Profiler 'gem4' => 0 // serverside items cant have more than 3 sockets. (custom profile thing) ); - DB::Aowow()->query('INSERT INTO ?_profiler_items (?#) VALUES (?a)', array_keys($data), array_values($data)); + DB::Aowow()->qry('INSERT INTO ::profiler_items %v', $data); } CLI::write(' ..inventory'); @@ -486,7 +489,7 @@ class Profiler 'hairstyle' => $char['hairStyle'], 'haircolor' => $char['hairColor'], 'features' => $char['facialStyle'], // maybe facetype - 'title' => $char['chosenTitle'] ? DB::Aowow()->selectCell('SELECT `id` FROM ?_titles WHERE `bitIdx` = ?d', $char['chosenTitle']) : 0, + 'title' => $char['chosenTitle'] ? DB::Aowow()->selectCell('SELECT `id` FROM ::titles WHERE `bitIdx` = %i', $char['chosenTitle']) : 0, 'playedtime' => $char['totaltime'], 'nomodelMask' => ($char['playerFlags'] & 0x400 ? (1 << SLOT_HEAD) : 0) | ($char['playerFlags'] & 0x800 ? (1 << SLOT_BACK) : 0), 'talenttree1' => 0, @@ -506,9 +509,9 @@ class Profiler // char is flagged for rename if ($char['at_login'] & 0x1) { - if ($ri = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $charGuid)) + if ($ri = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ::profiler_profiles WHERE `realm` = %i AND `realmGUID` = %i', $realmId, $charGuid)) $data['renameItr'] = $ri; - else if ($ri = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ?_profiler_profiles WHERE `realm` = ?d AND `custom` = 0 AND `name` = ?', $realmId, $char['name'])) + else if ($ri = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ::profiler_profiles WHERE `realm` = %i AND `custom` = 0 AND `name` = %s', $realmId, $char['name'])) $data['renameItr'] = ++$ri; else $data['renameItr'] = 1; @@ -519,14 +522,14 @@ class Profiler /* talents + glyphs */ /********************/ - $t = DB::Characters($realmId)->selectCol('SELECT `talentGroup` AS ARRAY_KEY, `spell` AS ARRAY_KEY2, `spell` FROM character_talent WHERE `guid` = ?d', $char['guid']); - $g = DB::Characters($realmId)->select('SELECT `talentGroup` AS ARRAY_KEY, `glyph1` AS "g1", `glyph2` AS "g4", `glyph3` AS "g5", `glyph4` AS "g2", `glyph5` AS "g3", `glyph6` AS "g6" FROM character_glyphs WHERE `guid` = ?d', $char['guid']); + $t = DB::Characters($realmId)->selectCol('SELECT `talentGroup` AS ARRAY_KEY, `spell` AS ARRAY_KEY2, `spell` FROM character_talent WHERE `guid` = %i', $char['guid']); + $g = DB::Characters($realmId)->selectAssoc('SELECT `talentGroup` AS ARRAY_KEY, `glyph1` AS "g1", `glyph2` AS "g4", `glyph3` AS "g5", `glyph4` AS "g2", `glyph5` AS "g3", `glyph6` AS "g6" FROM character_glyphs WHERE `guid` = %i', $char['guid']); for ($i = 0; $i < 2; $i++) { // talents for ($j = 0; $j < 3; $j++) { - $_ = DB::Aowow()->selectCol('SELECT `spell` AS ARRAY_KEY, MAX(IF(`spell` IN (?a), `rank`, 0)) FROM ?_talents WHERE `class` = ?d AND `tab` = ?d GROUP BY `id` ORDER BY `row`, `col` ASC', $t[$i] ?? [0], $cl->value, $j); + $_ = DB::Aowow()->selectCol('SELECT `spell` AS ARRAY_KEY, MAX(IF(`spell` IN %in, `rank`, 0)) FROM ::talents WHERE `class` = %i AND `tab` = %i GROUP BY `id` ORDER BY `row`, `col` ASC', $t[$i] ?? [0], $cl->value, $j); $data['talentbuild'.($i + 1)] .= implode('', $_); if ($data['activespec'] == $i) $data['talenttree'.($j + 1)] = array_sum($_); @@ -544,10 +547,10 @@ class Profiler { $gItems = DB::Aowow()->selectCol( 'SELECT i.`id` - FROM ?_glyphproperties gp - JOIN ?_spell s ON s.`effect1MiscValue` = gp.`id` AND s.`effect1Id` = ?d - JOIN ?_items i ON i.`class` = ?d AND i.`spellId1` = s.`id` AND (i.`cuFlags` & ?d) = 0 - WHERE gp.`id` IN (?a)', + FROM ::glyphproperties gp + JOIN ::spell s ON s.`effect1MiscValue` = gp.`id` AND s.`effect1Id` = %i + JOIN ::items i ON i.`class` = %i AND i.`spellId1` = s.`id` AND (i.`cuFlags` & %i) = 0 + WHERE gp.`id` IN %in', SPELL_EFFECT_APPLY_GLYPH, ITEM_CLASS_GLYPH, CUSTOM_DISABLED | CUSTOM_UNAVAILABLE | CUSTOM_EXCLUDE_FOR_LISTVIEW, $gProps ); @@ -585,7 +588,7 @@ class Profiler // enchantId => multiple spells => multiple items with varying itemlevels, quality, whatevs // cant reasonably get to the castItem from enchantId and slot - $profSpec = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `skillLevel` AS "1", `skillLine` AS "0" FROM ?_itemenchantment WHERE `id` IN (?a)', $permEnch); + $profSpec = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `skillLevel` AS "1", `skillLine` AS "0" FROM ::itemenchantment WHERE `id` IN %in', $permEnch); foreach ($permEnch as $slot => $eId) { if (!isset($profSpec[$eId])) @@ -612,19 +615,19 @@ class Profiler if ($cl == ChrClass::HUNTER) { - DB::Aowow()->query('DELETE FROM ?_profiler_pets WHERE `owner` = ?d', $profileId); - $pets = DB::Characters($realmId)->select('SELECT `id` AS ARRAY_KEY, `entry`, `modelId`, `name` FROM character_pet WHERE `owner` = ?d', $charGuid); + DB::Aowow()->qry('DELETE FROM ::profiler_pets WHERE `owner` = %i', $profileId); + $pets = DB::Characters($realmId)->selectAssoc('SELECT `id` AS ARRAY_KEY, `entry`, `modelId`, `name` FROM character_pet WHERE `owner` = %i', $charGuid); foreach ($pets as $petGuid => $petData) { - $petSpells = DB::Characters($realmId)->selectCol('SELECT `spell` FROM pet_spell WHERE `guid` = ?d', $petGuid); + $petSpells = DB::Characters($realmId)->selectCol('SELECT `spell` FROM pet_spell WHERE `guid` = %i', $petGuid); $morePet = DB::Aowow()->selectRow( 'SELECT IFNULL(c3.`id`, IFNULL(c2.`id`, IFNULL(c1.`id`, c.`id`))) AS "entry", p.`type`, c.`family` - FROM ?_pet p - JOIN ?_creature c ON c.`family` = p.`id` - LEFT JOIN ?_creature c1 ON c1.`difficultyEntry1` = c.`id` - LEFT JOIN ?_creature c2 ON c2.`difficultyEntry2` = c.`id` - LEFT JOIN ?_creature c3 ON c3.`difficultyEntry3` = c.`id` - WHERE c.`id` = ?d', + FROM ::pet p + JOIN ::creature c ON c.`family` = p.`id` + LEFT JOIN ::creature c1 ON c1.`difficultyEntry1` = c.`id` + LEFT JOIN ::creature c2 ON c2.`difficultyEntry2` = c.`id` + LEFT JOIN ::creature c3 ON c3.`difficultyEntry3` = c.`id` + WHERE c.`id` = %i', $petData['entry'] ); @@ -636,9 +639,9 @@ class Profiler $_ = DB::Aowow()->selectCol( 'SELECT IFNULL(t2.`rank`, 0) - FROM ?_talents t1 - LEFT JOIN (SELECT `id`, `rank` FROM ?_talents WHERE `spell` IN (?a)) t2 ON t2.`id` = t1.`id` - WHERE `class` = 0 AND `petTypeMask` = ?d + FROM ::talents t1 + LEFT JOIN (SELECT `id`, `rank` FROM ::talents WHERE `spell` IN %in) t2 ON t2.`id` = t1.`id` + WHERE `class` = 0 AND `petTypeMask` = %i GROUP BY t1.`id` ORDER BY t1.`row`, t1.`col`, t1.`id` ASC', $petSpells ?: [0], 1 << $morePet['type'] @@ -654,7 +657,7 @@ class Profiler 'talents' => implode('', $_) ); - DB::Aowow()->query('INSERT INTO ?_profiler_pets (?#) VALUES (?a)', array_keys($pet), array_values($pet)); + DB::Aowow()->qry('INSERT INTO ::profiler_pets %v', $pet); } CLI::write(' ..hunter pets'); @@ -667,105 +670,115 @@ class Profiler // done quests // - DB::Aowow()->query('DELETE FROM ?_profiler_completion_quests WHERE `id` = ?d', $profileId); + DB::Aowow()->qry('DELETE FROM ::profiler_completion_quests WHERE `id` = %i', $profileId); - if ($quests = DB::Characters($realmId)->select('SELECT ?d AS `id`, `quest` AS `questId` FROM character_queststatus_rewarded WHERE `guid` = ?d', $profileId, $char['guid'])) - foreach (Util::createSqlBatchInsert($quests) as $q) - DB::Aowow()->query('INSERT INTO ?_profiler_completion_quests (?#) VALUES '.$q, array_keys($quests[0])); + if ($quests = DB::Characters($realmId)->selectCol('SELECT `quest` FROM character_queststatus_rewarded WHERE `guid` = %i', $char['guid'])) + DB::Aowow()->qry('INSERT INTO ::profiler_completion_quests %m', array( + 'id' => array_fill(0, count($quests), $profileId), + 'questId' => $quests + )); CLI::write(' ..quests'); // known skills (professions only) // - DB::Aowow()->query('DELETE FROM ?_profiler_completion_skills WHERE `id` = ?d', $profileId); + DB::Aowow()->qry('DELETE FROM ::profiler_completion_skills WHERE `id` = %i', $profileId); - $skAllowed = DB::Aowow()->selectCol('SELECT `id` FROM ?_skillline WHERE `typeCat` IN (9, 11) AND (`cuFlags` & ?d) = 0', CUSTOM_EXCLUDE_FOR_LISTVIEW); - $skills = DB::Characters($realmId)->select('SELECT ?d AS `id`, `skill` AS `skillId`, `value`, `max` FROM character_skills WHERE `guid` = ?d AND `skill` IN (?a)', $profileId, $char['guid'], $skAllowed); - $racials = DB::Aowow()->select('SELECT `effect1MiscValue` AS ARRAY_KEY, `effect1DieSides` + `effect1BasePoints` AS qty, `reqRaceMask`, `reqClassMask` FROM ?_spell WHERE `typeCat` = -4 AND `effect1Id` = ?d AND `effect1AuraId` = ?d', SPELL_EFFECT_APPLY_AURA, SPELL_AURA_MOD_SKILL_TALENT); - - foreach ($skills as &$sk) // apply racial profession bonuses + $skAllowed = DB::Aowow()->selectCol('SELECT `id` FROM ::skillline WHERE `typeCat` IN (9, 11) AND (`cuFlags` & %i) = 0', CUSTOM_EXCLUDE_FOR_LISTVIEW); + if ($skills = DB::Characters($realmId)->selectAssoc('SELECT `skill`, `value`, `max` FROM character_skills WHERE `guid` = %i AND `skill` IN %in', $char['guid'], $skAllowed)) { - if (!isset($racials[$sk['skillId']])) - continue; + $racials = DB::Aowow()->selectAssoc('SELECT `effect1MiscValue` AS ARRAY_KEY, `effect1DieSides` + `effect1BasePoints` AS qty, `reqRaceMask`, `reqClassMask` FROM ::spell WHERE `typeCat` = -4 AND `effect1Id` = %i AND `effect1AuraId` = %i', SPELL_EFFECT_APPLY_AURA, SPELL_AURA_MOD_SKILL_TALENT); - $r = $racials[$sk['skillId']]; - if ($ra->matches($r['reqRaceMask']) && $cl->matches($r['reqClassMask'])) + foreach ($skills as &$sk) // apply racial profession bonuses { - $sk['value'] += $r['qty']; - $sk['max'] += $r['qty']; - } - } - unset($sk); + if (!isset($racials[$sk['skill']])) + continue; - if ($skills) - foreach (Util::createSqlBatchInsert($skills) as $sk) - DB::Aowow()->query('INSERT INTO ?_profiler_completion_skills (?#) VALUES '.$sk, array_keys($skills[0])); + $r = $racials[$sk['skill']]; + if ($ra->matches($r['reqRaceMask']) && $cl->matches($r['reqClassMask'])) + { + $sk['value'] += $r['qty']; + $sk['max'] += $r['qty']; + } + } + unset($sk); + + DB::Aowow()->qry('INSERT INTO ::profiler_completion_skills %m', array( + 'id' => array_fill(0, count($skills), $profileId), + 'skillId' => array_column($skills, 'skill'), + 'value' => array_column($skills, 'value'), + 'max' => array_column($skills, 'max') + )); + } CLI::write(' ..professions'); // reputation // - DB::Aowow()->query('DELETE FROM ?_profiler_completion_reputation WHERE `id` = ?d', $profileId); + DB::Aowow()->qry('DELETE FROM ::profiler_completion_reputation WHERE `id` = %i', $profileId); // get base values for this race/class $reputation = []; $baseRep = DB::Aowow()->selectCol( - 'SELECT `id` AS ARRAY_KEY, `baseRepValue1` FROM ?_factions WHERE `baseRepValue1` AND (`baseRepRaceMask1` & ?d OR (`baseRepClassMask1` AND NOT `baseRepRaceMask1`)) AND ((`baseRepClassMask1` & ?d) OR NOT `baseRepClassMask1`) UNION - SELECT `id` AS ARRAY_KEY, `baseRepValue2` FROM ?_factions WHERE `baseRepValue2` AND (`baseRepRaceMask2` & ?d OR (`baseRepClassMask2` AND NOT `baseRepRaceMask2`)) AND ((`baseRepClassMask2` & ?d) OR NOT `baseRepClassMask2`) UNION - SELECT `id` AS ARRAY_KEY, `baseRepValue3` FROM ?_factions WHERE `baseRepValue3` AND (`baseRepRaceMask3` & ?d OR (`baseRepClassMask3` AND NOT `baseRepRaceMask3`)) AND ((`baseRepClassMask3` & ?d) OR NOT `baseRepClassMask3`) UNION - SELECT `id` AS ARRAY_KEY, `baseRepValue4` FROM ?_factions WHERE `baseRepValue4` AND (`baseRepRaceMask4` & ?d OR (`baseRepClassMask4` AND NOT `baseRepRaceMask4`)) AND ((`baseRepClassMask4` & ?d) OR NOT `baseRepClassMask4`)', + 'SELECT `id` AS ARRAY_KEY, `baseRepValue1` FROM ::factions WHERE `baseRepValue1` AND (`baseRepRaceMask1` & %i OR (`baseRepClassMask1` AND NOT `baseRepRaceMask1`)) AND ((`baseRepClassMask1` & %i) OR NOT `baseRepClassMask1`) UNION + SELECT `id` AS ARRAY_KEY, `baseRepValue2` FROM ::factions WHERE `baseRepValue2` AND (`baseRepRaceMask2` & %i OR (`baseRepClassMask2` AND NOT `baseRepRaceMask2`)) AND ((`baseRepClassMask2` & %i) OR NOT `baseRepClassMask2`) UNION + SELECT `id` AS ARRAY_KEY, `baseRepValue3` FROM ::factions WHERE `baseRepValue3` AND (`baseRepRaceMask3` & %i OR (`baseRepClassMask3` AND NOT `baseRepRaceMask3`)) AND ((`baseRepClassMask3` & %i) OR NOT `baseRepClassMask3`) UNION + SELECT `id` AS ARRAY_KEY, `baseRepValue4` FROM ::factions WHERE `baseRepValue4` AND (`baseRepRaceMask4` & %i OR (`baseRepClassMask4` AND NOT `baseRepRaceMask4`)) AND ((`baseRepClassMask4` & %i) OR NOT `baseRepClassMask4`)', $ra->toMask(), $cl->toMask(), $ra->toMask(), $cl->toMask(), $ra->toMask(), $cl->toMask(), $ra->toMask(), $cl->toMask() ); - if ($reputation = DB::Characters($realmId)->select('SELECT ?d AS `id`, `faction` AS `factionId`, `standing` FROM character_reputation WHERE `guid` = ?d AND (`flags` & 0x4) = 0', $profileId, $char['guid'])) + $insCols = []; + if ($reputation = DB::Characters($realmId)->selectAssoc('SELECT `faction`, `standing` FROM character_reputation WHERE `guid` = %i AND (`flags` & 0x4) = 0', $char['guid'])) { // merge back base values for encountered factions - foreach ($reputation as &$set) + foreach ($reputation as $set) { - if (empty($baseRep[$set['factionId']])) - continue; + $insCols['id'][] = $profileId; + $insCols['factionId'][] = $set['faction']; + $insCols['standing'][] = $set['standing'] + ($baseRep[$set['faction']] ?? 0); - $set['standing'] += $baseRep[$set['factionId']]; - unset($baseRep[$set['factionId']]); + unset($baseRep[$set['faction']]); } } // insert base values for not yet encountered factions foreach ($baseRep as $id => $val) - $reputation[] = array( - 'id' => $profileId, - 'factionId' => $id, - 'standing' => $val - ); + { + $insCols['id'][] = $profileId; + $insCols['factionId'][] = $id; + $insCols['standing'][] = $val; + } - foreach (Util::createSqlBatchInsert($reputation) as $rep) - DB::Aowow()->query('INSERT INTO ?_profiler_completion_reputation (?#) VALUES '.$rep, array_keys($reputation[0])); + DB::Aowow()->qry('INSERT INTO ::profiler_completion_reputation %m', $insCols); CLI::write(' ..reputation'); // known titles // - DB::Aowow()->query('DELETE FROM ?_profiler_completion_titles WHERE `id` = ?d', $profileId); + DB::Aowow()->qry('DELETE FROM ::profiler_completion_titles WHERE `id` = %i', $profileId); if ($indizes = Util::indexBitBlob($char['knownTitles'])) - DB::Aowow()->query('INSERT INTO ?_profiler_completion_titles SELECT ?d, `id` FROM ?_titles WHERE `bitIdx` IN (?a)', $profileId, $indizes); + DB::Aowow()->qry('INSERT INTO ::profiler_completion_titles SELECT %i, `id` FROM ::titles WHERE `bitIdx` IN %in', $profileId, $indizes); CLI::write(' ..titles'); // achievements // - DB::Aowow()->query('DELETE FROM ?_profiler_completion_achievements WHERE `id` = ?d', $profileId); + DB::Aowow()->qry('DELETE FROM ::profiler_completion_achievements WHERE `id` = %i', $profileId); - if ($achievements = DB::Characters($realmId)->select('SELECT ?d AS id, `achievement` AS `achievementId`, `date` FROM character_achievement WHERE `guid` = ?d', $profileId, $char['guid'])) + if ($achievements = DB::Characters($realmId)->selectAssoc('SELECT `achievement`, `date` FROM character_achievement WHERE `guid` = %i', $char['guid'])) { - foreach (Util::createSqlBatchInsert($achievements) as $a) - DB::Aowow()->query('INSERT INTO ?_profiler_completion_achievements (?#) VALUES '.$a, array_keys($achievements[0])); + DB::Aowow()->qry('INSERT INTO ::profiler_completion_achievements %m', array( + 'id' => array_fill(0, count($achievements), $profileId), + 'achievementId' => array_column($achievements, 'achievement'), + 'date' => array_column($achievements, 'date') + )); - $data['achievementpoints'] = DB::Aowow()->selectCell('SELECT SUM(`points`) FROM ?_achievement WHERE `id` IN (?a) AND (`flags` & ?d) = 0', array_column($achievements, 'achievementId'), ACHIEVEMENT_FLAG_COUNTER); + $data['achievementpoints'] = DB::Aowow()->selectCell('SELECT SUM(`points`) FROM ::achievement WHERE `id` IN %in AND (`flags` & %i) = 0', array_column($achievements, 'achievement'), ACHIEVEMENT_FLAG_COUNTER); } CLI::write(' ..achievements'); @@ -773,13 +786,18 @@ class Profiler // raid progression // - DB::Aowow()->query('DELETE FROM ?_profiler_completion_statistics WHERE `id` = ?d', $profileId); + DB::Aowow()->qry('DELETE FROM ::profiler_completion_statistics WHERE `id` = %i', $profileId); - if ($progress = DB::Characters($realmId)->select('SELECT ?d AS `id`, `criteria` AS `achievementId`, `date`, `counter` FROM character_achievement_progress WHERE `guid` = ?d AND `criteria` IN (?a)', $profileId, $char['guid'], self::$raidProgression)) + if ($progress = DB::Characters($realmId)->selectAssoc('SELECT `criteria`, `date`, `counter` FROM character_achievement_progress WHERE `guid` = %i AND `criteria` IN %in', $char['guid'], self::$raidProgression)) { - array_walk($progress, function (&$val) { $val['achievementId'] = array_search($val['achievementId'], self::$raidProgression); }); - foreach (Util::createSqlBatchInsert($progress) as $p) - DB::Aowow()->query('INSERT INTO ?_profiler_completion_statistics (?#) VALUES '.$p, array_keys($progress[0])); + array_walk($progress, fn(&$x) => $x['achievement'] = array_search($x['criteria'], self::$raidProgression)); + + DB::Aowow()->qry('INSERT INTO ::profiler_completion_statistics %m', array( + 'id' => array_fill(0, count($progress), $profileId), + 'achievementId' => array_column($progress, 'achievement'), + 'date' => array_column($progress, 'date'), + 'counter' => array_column($progress, 'counter') + )); } CLI::write(' ..raid progression'); @@ -787,22 +805,24 @@ class Profiler // known spells // - DB::Aowow()->query('DELETE FROM ?_profiler_completion_spells WHERE `id` = ?d', $profileId); + DB::Aowow()->qry('DELETE FROM ::profiler_completion_spells WHERE `id` = %i', $profileId); - if ($spells = DB::Characters($realmId)->select('SELECT ?d AS `id`, `spell` AS `spellId` FROM character_spell WHERE `guid` = ?d AND `disabled` = 0', $profileId, $char['guid'])) - foreach (Util::createSqlBatchInsert($spells) as $s) - DB::Aowow()->query('INSERT INTO ?_profiler_completion_spells (?#) VALUES '.$s, array_keys($spells[0])); + if ($spells = DB::Characters($realmId)->selectCol('SELECT `spell` FROM character_spell WHERE `guid` = %i AND `disabled` = 0', $char['guid'])) + DB::Aowow()->qry('INSERT INTO ::profiler_completion_spells %m', array( + 'id' => array_fill(0, count($spells), $profileId), + 'questId' => $spells + )); // apply auto-learned spells from trade skills if ($skills) - DB::Aowow()->query( - 'INSERT INTO ?_profiler_completion_spells - SELECT ?d, `spellId` - FROM ?_skilllineability - WHERE `skillLineId` IN (?a) AND + DB::Aowow()->qry( + 'INSERT INTO ::profiler_completion_spells + SELECT %i, `spellId` + FROM ::skilllineability + WHERE `skillLineId` IN %in AND `acquireMethod` = 1 AND - (`reqRaceMask` = 0 OR `reqRaceMask` & ?d) AND - (`reqClassMask` = 0 OR `reqClassMask` & ?d)', + (`reqRaceMask` = 0 OR `reqRaceMask` & %i) AND + (`reqClassMask` = 0 OR `reqClassMask` & %i)', $profileId, array_column($skills, 'skillId'), $ra->toMask(), @@ -817,10 +837,10 @@ class Profiler /****************/ // guilds - if ($guild = DB::Characters($realmId)->selectRow('SELECT g.`name` AS `name`, g.`guildid` AS `id`, gm.`rank` FROM guild_member gm JOIN guild g ON g.`guildid` = gm.`guildid` WHERE gm.`guid` = ?d', $char['guid'])) + if ($guild = DB::Characters($realmId)->selectRow('SELECT g.`name` AS `name`, g.`guildid` AS `id`, gm.`rank` FROM guild_member gm JOIN guild g ON g.`guildid` = gm.`guildid` WHERE gm.`guid` = %i', $char['guid'])) { $guildId = 0; - if (!($guildId = DB::Aowow()->selectCell('SELECT id FROM ?_profiler_guild WHERE realm = ?d AND realmGUID = ?d', $realmId, $guild['id']))) + if (!($guildId = DB::Aowow()->selectCell('SELECT id FROM ::profiler_guild WHERE realm = %i AND realmGUID = %i', $realmId, $guild['id']))) { $gData = array( // only most basic data 'realm' => $realmId, @@ -830,7 +850,7 @@ class Profiler 'stub' => 1 ); - $guildId = DB::Aowow()->query('INSERT IGNORE INTO ?_profiler_guild (?#) VALUES (?a)', array_keys($gData), array_values($gData)); + $guildId = DB::Aowow()->qry('INSERT IGNORE INTO ::profiler_guild %v', $gData); } $data['guild'] = $guildId; @@ -841,11 +861,11 @@ class Profiler // arena teams - $teams = DB::Characters($realmId)->select('SELECT at.`arenaTeamId` AS ARRAY_KEY, at.`name`, at.`type`, IF(at.`captainGuid` = atm.`guid`, 1, 0) AS `captain`, atm.* FROM arena_team at JOIN arena_team_member atm ON atm.`arenaTeamId` = at.`arenaTeamId` WHERE atm.`guid` = ?d', $char['guid']); + $teams = DB::Characters($realmId)->selectAssoc('SELECT at.`arenaTeamId` AS ARRAY_KEY, at.`name`, at.`type`, IF(at.`captainGuid` = atm.`guid`, 1, 0) AS `captain`, atm.* FROM arena_team at JOIN arena_team_member atm ON atm.`arenaTeamId` = at.`arenaTeamId` WHERE atm.`guid` = %i', $char['guid']); foreach ($teams as $rGuid => $t) { $teamId = 0; - if (!($teamId = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_arena_team WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $rGuid))) + if (!($teamId = DB::Aowow()->selectCell('SELECT `id` FROM ::profiler_arena_team WHERE `realm` = %i AND `realmGUID` = %i', $realmId, $rGuid))) { $team = array( // only most basic data 'realm' => $realmId, @@ -856,7 +876,7 @@ class Profiler 'stub' => 1 ); - $teamId = DB::Aowow()->query('INSERT IGNORE INTO ?_profiler_arena_team (?#) VALUES (?a)', array_keys($team), array_values($team)); + $teamId = DB::Aowow()->qry('INSERT IGNORE INTO ::profiler_arena_team %v', $team); } $member = array( @@ -870,16 +890,16 @@ class Profiler 'personalRating' => $t['personalRating'] ); - // Delete members from other teams of the same type - DB::Aowow()->query( + // delete members from other teams of the same type + DB::Aowow()->qry( 'DELETE atm - FROM ?_profiler_arena_team_member atm - JOIN ?_profiler_arena_team at ON atm.`arenaTeamId` = at.`id` AND at.`type` = ?d - WHERE atm.`profileId` = ?d AND atm.`arenaTeamId` <> ?d', + FROM ::profiler_arena_team_member atm + JOIN ::profiler_arena_team at ON atm.`arenaTeamId` = at.`id` AND at.`type` = %i + WHERE atm.`profileId` = %i AND atm.`arenaTeamId` <> %i', $t['type'], $profileId, $teamId ); - DB::Aowow()->query('INSERT INTO ?_profiler_arena_team_member (?#) VALUES (?a) ON DUPLICATE KEY UPDATE ?a', array_keys($member), array_values($member), array_slice($member, 2)); + DB::Aowow()->qry('INSERT INTO ::profiler_arena_team_member %v ON DUPLICATE KEY UPDATE %a', $member, array_slice($member, 2)); } CLI::write(' ..associated arena teams'); @@ -888,15 +908,15 @@ class Profiler /* mark char as done */ /*********************/ - 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 `stub` = 0 WHERE `id` = ?d', $profileId); + if (DB::Aowow()->qry('UPDATE ::profiler_profiles SET %a WHERE `realm` = %i AND `realmGUID` = %i', $data, $realmId, $charGuid) !== null) + DB::Aowow()->qry('UPDATE ::profiler_profiles SET `stub` = 0 WHERE `id` = %i', $profileId); return self::FETCH_RESULT_OK; } public static function getGuildFromRealm(int $realmId, int $guildGuid) : int { - $guild = DB::Characters($realmId)->selectRow('SELECT `guildId`, `name`, `createDate`, `info`, `backgroundColor`, `emblemStyle`, `emblemColor`, `borderStyle`, `borderColor` FROM guild WHERE `guildId` = ?d', $guildGuid); + $guild = DB::Characters($realmId)->selectRow('SELECT `guildId`, `name`, `createDate`, `info`, `backgroundColor`, `emblemStyle`, `emblemColor`, `borderStyle`, `borderColor` FROM guild WHERE `guildId` = %i', $guildGuid); if (!$guild) return self::FETCH_RESULT_ERR_NOT_FOUND; @@ -904,7 +924,7 @@ class Profiler return self::FETCH_RESULT_ERR_NAME_EMPTY; // reminder: this query should not fail: a placeholder entry is created as soon as a team listview is created or team detail page is called - $guildId = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_guild WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $guild['guildId']); + $guildId = DB::Aowow()->selectCell('SELECT `id` FROM ::profiler_guild WHERE `realm` = %i AND `realmGUID` = %i', $realmId, $guild['guildId']); CLI::write('fetching guild #'.$guildGuid.' from realm #'.$realmId); CLI::write('writing...'); @@ -917,13 +937,13 @@ class Profiler unset($guild['guildId']); $guild['nameUrl'] = self::urlize($guild['name']); - DB::Aowow()->query('UPDATE ?_profiler_guild SET ?a WHERE `realm` = ?d AND `realmGUID` = ?d', $guild, $realmId, $guildGuid); + DB::Aowow()->qry('UPDATE ::profiler_guild SET %a WHERE `realm` = %i AND `realmGUID` = %i', $guild, $realmId, $guildGuid); // ranks - DB::Aowow()->query('DELETE FROM ?_profiler_guild_rank WHERE `guildId` = ?d', $guildId); - if ($ranks = DB::Characters($realmId)->select('SELECT ?d AS `guildId`, `rid` AS "rank", `rname` AS "name" FROM guild_rank WHERE `guildid` = ?d', $guildId, $guildGuid)) - foreach (Util::createSqlBatchInsert($ranks) as $r) - DB::Aowow()->query('INSERT INTO ?_profiler_guild_rank (?#) VALUES '.$r, array_keys(reset($ranks))); + DB::Aowow()->qry('DELETE FROM ::profiler_guild_rank WHERE `guildId` = %i', $guildId); + if ($ranks = DB::Characters($realmId)->selectAssoc('SELECT %i AS `guildId`, `rid` AS "rank", `rname` AS "name" FROM guild_rank WHERE `guildid` = %i', $guildId, $guildGuid)) + foreach ($ranks as $r) // at most 10 per guild. don't bother setting up a multi-insert (%m) + DB::Aowow()->qry('INSERT INTO ::profiler_guild_rank %v', $r); CLI::write(' ..guild data'); @@ -953,14 +973,14 @@ class Profiler /* mark guild as done */ /*********************/ - DB::Aowow()->query('UPDATE ?_profiler_guild SET `stub` = 0 WHERE `id` = ?d', $guildId); + DB::Aowow()->qry('UPDATE ::profiler_guild SET `stub` = 0 WHERE `id` = %i', $guildId); return self::FETCH_RESULT_OK; } public static function getArenaTeamFromRealm(int $realmId, int $teamGuid) : int { - $team = DB::Characters($realmId)->selectRow('SELECT `arenaTeamId`, `name`, `type`, `captainGuid`, `rating`, `seasonGames`, `seasonWins`, `weekGames`, `weekWins`, `rank`, `backgroundColor`, `emblemStyle`, `emblemColor`, `borderStyle`, `borderColor` FROM arena_team WHERE `arenaTeamId` = ?d', $teamGuid); + $team = DB::Characters($realmId)->selectRow('SELECT `arenaTeamId`, `name`, `type`, `captainGuid`, `rating`, `seasonGames`, `seasonWins`, `weekGames`, `weekWins`, `rank`, `backgroundColor`, `emblemStyle`, `emblemColor`, `borderStyle`, `borderColor` FROM arena_team WHERE `arenaTeamId` = %i', $teamGuid); if (!$team) return self::FETCH_RESULT_ERR_NOT_FOUND; @@ -968,7 +988,7 @@ class Profiler return self::FETCH_RESULT_ERR_NAME_EMPTY; // reminder: this query should not fail: a placeholder entry is created as soon as a team listview is created or team detail page is called - $teamId = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_arena_team WHERE `realm` = ?d AND `realmGUID` = ?d', $realmId, $team['arenaTeamId']); + $teamId = DB::Aowow()->selectCell('SELECT `id` FROM ::profiler_arena_team WHERE `realm` = %i AND `realmGUID` = %i', $realmId, $team['arenaTeamId']); CLI::write('fetching arena team #'.$teamGuid.' from realm #'.$realmId); CLI::write('writing...'); @@ -979,11 +999,10 @@ class Profiler /*************/ $captain = $team['captainGuid']; - unset($team['captainGuid']); - unset($team['arenaTeamId']); + unset($team['captainGuid'], $team['arenaTeamId']); $team['nameUrl'] = self::urlize($team['name']); - DB::Aowow()->query('UPDATE ?_profiler_arena_team SET ?a WHERE `realm` = ?d AND `realmGUID` = ?d', $team, $realmId, $teamGuid); + DB::Aowow()->qry('UPDATE ::profiler_arena_team SET %a WHERE `realm` = %i AND `realmGUID` = %i', $team, $realmId, $teamGuid); CLI::write(' ..team data'); @@ -992,14 +1011,14 @@ class Profiler /* Member Data */ /***************/ - $members = DB::Characters($realmId)->select( + $members = DB::Characters($realmId)->selectAssoc( 'SELECT atm.`guid` AS ARRAY_KEY, atm.`arenaTeamId`, atm.`weekGames`, atm.`weekWins`, atm.`seasonGames`, atm.`seasonWins`, atm.`personalrating` FROM arena_team_member atm JOIN characters c ON c.`guid` = atm.`guid` AND c.`deleteInfos_Account` IS NULL AND - c.`level` <= ?d AND - (c.`extra_flags` & ?d) = 0 - WHERE `arenaTeamId` = ?d', + c.`level` <= %i AND + (c.`extra_flags` & %i) = 0 + WHERE `arenaTeamId` = %i', MAX_LEVEL, self::CHAR_GMFLAGS, $teamGuid @@ -1027,21 +1046,21 @@ class Profiler $members[$mGuid]['profileId'] = $mProfiles->getField('id'); } - // Delete members from other teams of the same type... - DB::Aowow()->query( + // delete members from other teams of the same type... + DB::Aowow()->qry( 'DELETE atm - FROM ?_profiler_arena_team_member atm - JOIN ?_profiler_arena_team at ON atm.`arenaTeamId` = at.`id` AND at.`type` = ?d - WHERE atm.`profileId` IN (?a)', + FROM ::profiler_arena_team_member atm + JOIN ::profiler_arena_team at ON atm.`arenaTeamId` = at.`id` AND at.`type` = %i + WHERE atm.`profileId` IN %in', $team['type'], array_column($members, 'profileId') ); // ...and purge this teams member - DB::Aowow()->query('DELETE FROM ?_profiler_arena_team_member WHERE `arenaTeamId` = ?d', $teamId); + DB::Aowow()->qry('DELETE FROM ::profiler_arena_team_member WHERE `arenaTeamId` = %i', $teamId); - foreach (Util::createSqlBatchInsert($members) as $m) - DB::Aowow()->query('INSERT INTO ?_profiler_arena_team_member (?#) VALUES '.$m, array_keys(reset($members))); + foreach ($members as $m) // at most 10 per team (5x2) don't bother setting up multi-insert (%m) + DB::Aowow()->qry('INSERT INTO ::profiler_arena_team_member %v', $m); CLI::write(' ..team members'); @@ -1050,7 +1069,7 @@ class Profiler /* mark team as done */ /*********************/ - DB::Aowow()->query('UPDATE ?_profiler_arena_team SET `stub` = 0 WHERE `id` = ?d', $teamId); + DB::Aowow()->qry('UPDATE ::profiler_arena_team SET `stub` = 0 WHERE `id` = %i', $teamId); return self::FETCH_RESULT_OK; } diff --git a/includes/components/report.class.php b/includes/components/report.class.php index a4ca9457..26b4ca63 100644 --- a/includes/components/report.class.php +++ b/includes/components/report.class.php @@ -146,9 +146,19 @@ class Report private function checkTargetContext(?string $url) : int { - // check already reported - $field = User::isLoggedIn() ? 'userId' : 'ip'; - if (DB::Aowow()->selectCell('SELECT 1 FROM ?_reports WHERE `mode` = ?d AND `reason`= ?d AND `subject` = ?d{ AND `url` = ?} AND ?# = ?', $this->mode, $this->reason, $this->subject, $url ?: DBSIMPLE_SKIP, $field, User::$id ?: User::$ip)) + $where = array( + ['`mode` = %i ', $this->mode], + ['`reason`= %i ', $this->reason], + ['`subject` = %i', $this->subject], + ); + if (User::isLoggedIn()) // check already reported + $where[] = ['`userId` = %i', User::$id]; + else + $where[] = ['`ip` = %s', User::$ip]; + if ($url) + $where[] = ['`url` = %s', $url]; + + if (DB::Aowow()->selectCell('SELECT 1 FROM ::reports WHERE %and', $where)) return self::ERR_ALREADY_REPORTED; // check targeted post/postOwner staff status @@ -157,9 +167,9 @@ class Report { $roles = User::$groups; if ($this->mode == self::MODE_COMMENT) - $roles = DB::Aowow()->selectCell('SELECT `roles` FROM ?_comments WHERE `id` = ?d', $this->subject); + $roles = DB::Aowow()->selectCell('SELECT `roles` FROM ::comments WHERE `id` = %i', $this->subject); // else if if ($this->mode == self::MODE_FORUM_POST) - // $roles = DB::Aowow()->selectCell('SELECT `roles` FROM ?_forum_posts WHERE `id` = ?d', $this->subject); + // $roles = DB::Aowow()->selectCell('SELECT `roles` FROM ::forum_posts WHERE `id` = %i', $this->subject); return $roles & $ctxCheck ? self::ERR_NONE : self::ERR_MISCELLANEOUS; } @@ -238,7 +248,7 @@ class Report if ($email) $update['email'] = $email; - return DB::Aowow()->query('INSERT INTO ?_reports (?#) VALUES (?a)', array_keys($update), array_values($update)); + return DB::Aowow()->qry('INSERT INTO ::reports %v', $update); } public function getSimilar(int ...$status) : array @@ -250,8 +260,8 @@ class Report if ($s < self::STATUS_OPEN || $s > self::STATUS_CLOSED_SOLVED) unset($s); - return DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, r.* FROM ?_reports r WHERE {`status` IN (?a) AND }`mode` = ?d AND `reason` = ?d AND `subject` = ?d', - $status ?: DBSIMPLE_SKIP, $this->mode, $this->reason, $this->subject); + return DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, r.* FROM ::reports r WHERE %if', $status, '`status` IN %in AND', $status, '%end `mode` = %i AND `reason` = %i AND `subject` = %i', + $this->mode, $this->reason, $this->subject); } public function close(int $closeStatus, bool $inclAssigned = false) : bool @@ -266,10 +276,10 @@ class Report if ($inclAssigned) $fromStatus[] = self::STATUS_ASSIGNED; - if ($reports = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `userId` FROM ?_reports WHERE `status` IN (?a) AND `mode` = ?d AND `reason` = ?d AND `subject` = ?d', + if ($reports = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `userId` FROM ::reports WHERE `status` IN %in AND `mode` = %i AND `reason` = %i AND `subject` = %i', $fromStatus, $this->mode, $this->reason, $this->subject)) { - DB::Aowow()->query('UPDATE ?_reports SET `status` = ?d, `assigned` = 0 WHERE `id` IN (?a)', $closeStatus, array_keys($reports)); + DB::Aowow()->qry('UPDATE ::reports SET `status` = %i, `assigned` = 0 WHERE `id` IN %in', $closeStatus, array_keys($reports)); foreach ($reports as $rId => $uId) Util::gainSiteReputation($uId, $closeStatus == self::STATUS_CLOSED_SOLVED ? SITEREP_ACTION_GOOD_REPORT : SITEREP_ACTION_BAD_REPORT, ['id' => $rId]); diff --git a/includes/components/response/baseresponse.class.php b/includes/components/response/baseresponse.class.php index 98e4bb71..29c0bbc2 100644 --- a/includes/components/response/baseresponse.class.php +++ b/includes/components/response/baseresponse.class.php @@ -18,12 +18,12 @@ trait TrRecoveryHelper return Lang::main('intError'); // check if already processing - if ($_ = DB::Aowow()->selectCell('SELECT `statusTimer` - UNIX_TIMESTAMP() FROM ?_account WHERE `email` = ? AND `status` > ?d AND `statusTimer` > UNIX_TIMESTAMP()', $email, ACC_STATUS_NEW)) + if ($_ = DB::Aowow()->selectCell('SELECT `statusTimer` - UNIX_TIMESTAMP() FROM ::account WHERE `email` = %s AND `status` > %i AND `statusTimer` > UNIX_TIMESTAMP()', $email, ACC_STATUS_NEW)) return Lang::account('inputbox', 'error', 'isRecovering', [DateTime::formatTimeElapsed($_ * 1000)]); // create new token and write to db $token = Util::createHash(); - if (!DB::Aowow()->query('UPDATE ?_account SET `token` = ?, `status` = ?d, `statusTimer` = UNIX_TIMESTAMP() + ?d WHERE `email` = ?', $token, $newStatus, Cfg::get('ACC_RECOVERY_DECAY'), $email)) + if (!DB::Aowow()->qry('UPDATE ::account SET `token` = %s, `status` = %i, `statusTimer` = UNIX_TIMESTAMP() + %i WHERE `email` = %s', $token, $newStatus, Cfg::get('ACC_RECOVERY_DECAY'), $email)) return Lang::main('intError'); // send recovery mail @@ -544,9 +544,11 @@ abstract class BaseResponse protected function sumSQLStats() : void { - Util::arraySumByKey(self::$sql, DB::Aowow()->getStatistics(), DB::World()->getStatistics()); - foreach (Profiler::getRealms() as $rId => $_) - Util::arraySumByKey(self::$sql, DB::Characters($rId)->getStatistics()); + self::$sql = array( + 'count' => \dibi::$numOfQueries, + 'time' => \dibi::$totalTime, + 'elapsed' => \dibi::$elapsedTime + ); } protected function sendNoCacheHeader() diff --git a/includes/components/response/templateresponse.class.php b/includes/components/response/templateresponse.class.php index a723f111..d2eb3c94 100644 --- a/includes/components/response/templateresponse.class.php +++ b/includes/components/response/templateresponse.class.php @@ -172,7 +172,7 @@ class TemplateResponse extends BaseResponse array_push($this->scripts, [SC_CSS_FILE, 'css/staff.css'], [SC_JS_FILE, 'js/staff.js']); // get alt header logo - if ($ahl = DB::Aowow()->selectCell('SELECT `altHeaderLogo` FROM ?_home_featuredbox WHERE ?d BETWEEN `startDate` AND `endDate` ORDER BY `id` DESC', time())) + if ($ahl = DB::Aowow()->selectCell('SELECT `altHeaderLogo` FROM ::home_featuredbox WHERE %i BETWEEN `startDate` AND `endDate` ORDER BY `id` DESC', time())) $this->headerLogo = Util::defStatic($ahl); if ($this->pageName) @@ -398,14 +398,12 @@ class TemplateResponse extends BaseResponse } // fetch announcements - $fromDB = DB::Aowow()->select( + $fromDB = DB::Aowow()->selectAssoc( 'SELECT `id`, `mode`, `status`, `name`, `style`, `text_loc0`, `text_loc2`, `text_loc3`, `text_loc4`, `text_loc6`, `text_loc8` - FROM ?_announcements - WHERE (`status` = ?d { OR `status` = ?d } ) AND - (`page` = "*" { OR `page` = ? } ) AND - (`groupMask` = 0 OR `groupMask` & ?d)', - Announcement::STATUS_ENABLED, User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU) ? Announcement::STATUS_DISABLED : DBSIMPLE_SKIP, - $onlyGenerics || !$this->pageName ? DBSIMPLE_SKIP : $this->pageName, + FROM ::announcements + WHERE (`page` = "*" %if', !$onlyGenerics && $this->pageName, 'OR `page` = %s', $this->pageName, '%end) AND + `status` IN (%i) AND (`groupMask` = 0 OR `groupMask` & %i)', + User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU) ? [Announcement::STATUS_ENABLED, Announcement::STATUS_DISABLED] : [Announcement::STATUS_ENABLED], User::$groups ); @@ -424,13 +422,13 @@ class TemplateResponse extends BaseResponse $article = []; if (isset($this->guideRevision)) - $article = DB::Aowow()->selectRow('SELECT `article`, `locale`, `editAccess` FROM ?_articles WHERE `type` = ?d AND `typeId` = ?d AND `rev` = ?d', + $article = DB::Aowow()->selectRow('SELECT `article`, `locale`, `editAccess` FROM ::articles WHERE `type` = %i AND `typeId` = %i AND `rev` = %i', Type::GUIDE, $this->typeId, $this->guideRevision); if (!$article && !empty($this->gPageInfo['articleUrl'])) - $article = DB::Aowow()->selectRow('SELECT `article`, `locale`, `editAccess` FROM ?_articles WHERE `url` = ? AND `locale` IN (?a) ORDER BY `locale` DESC, `rev` DESC LIMIT 1', + $article = DB::Aowow()->selectRow('SELECT `article`, `locale`, `editAccess` FROM ::articles WHERE `url` = %s AND `locale` IN %in ORDER BY `locale` DESC, `rev` DESC LIMIT 1', $this->gPageInfo['articleUrl'], [Lang::getLocale()->value, Locale::EN->value]); if (!$article && !empty($this->type) && isset($this->typeId)) - $article = DB::Aowow()->selectRow('SELECT `article`, `locale`, `editAccess` FROM ?_articles WHERE `type` = ?d AND `typeId` = ?d AND `locale` IN (?a) ORDER BY `locale` DESC, `rev` DESC LIMIT 1', + $article = DB::Aowow()->selectRow('SELECT `article`, `locale`, `editAccess` FROM ::articles WHERE `type` = %i AND `typeId` = %i AND `locale` IN (%i) ORDER BY `locale` DESC, `rev` DESC LIMIT 1', $this->type, $this->typeId, [Lang::getLocale()->value, Locale::EN->value]); if (!$article) diff --git a/includes/components/screenshotmgr.class.php b/includes/components/screenshotmgr.class.php index 49beb62a..be782877 100644 --- a/includes/components/screenshotmgr.class.php +++ b/includes/components/screenshotmgr.class.php @@ -100,29 +100,23 @@ class ScreenshotMgr extends ImageUpload public static function getScreenshots(int $type = 0, int $typeId = 0, $userId = 0, ?int &$nFound = 0) : array { - $screenshots = DB::Aowow()->select( + if ($userId) + $where = [['s.`userIdOwner` = %i', $userId]]; + else + $where = [['s.`type` = %i', $type], ['s.`typeId` = %i', $typeId]]; + + $screenshots = DB::Aowow()->selectAssoc( 'SELECT s.`id`, a.`username` AS "user", s.`date`, s.`width`, s.`height`, s.`type`, s.`typeId`, s.`caption`, s.`status`, s.`status` AS "flags" - FROM ?_screenshots s - LEFT JOIN ?_account a ON s.`userIdOwner` = a.`id` - WHERE - { s.`type` = ?d } - { AND s.`typeId` = ?d } - { s.`userIdOwner` = ?d } - { LIMIT ?d }', - $userId ? DBSIMPLE_SKIP : $type, - $userId ? DBSIMPLE_SKIP : $typeId, - $userId ? $userId : DBSIMPLE_SKIP, - $userId || $type ? DBSIMPLE_SKIP : 100 + FROM ::screenshots s + LEFT JOIN ::account a ON s.`userIdOwner` = a.`id` + WHERE %and + %lmt', + $where, $userId || $type ? PHP_INT_MAX : 100 ); $num = []; foreach ($screenshots as $s) - { - if (empty($num[$s['type']][$s['typeId']])) - $num[$s['type']][$s['typeId']] = 1; - else - $num[$s['type']][$s['typeId']]++; - } + $num[$s['type']][$s['typeId']] = ($num[$s['type']][$s['typeId']] ?? 0) + 1; $nFound = 0; @@ -177,15 +171,7 @@ class ScreenshotMgr extends ImageUpload { // i GUESS .. ss_getALL ? everything : pending $nFound = 0; - $pages = DB::Aowow()->select( - 'SELECT s.`type`, s.`typeId`, COUNT(1) AS "count", MIN(s.`date`) AS "date" - FROM ?_screenshots s - { WHERE (s.`status` & ?d) = 0 } - GROUP BY s.`type`, s.`typeId`', - $all ? DBSIMPLE_SKIP : CC_FLAG_APPROVED | CC_FLAG_DELETED - ); - - if ($pages) + if ($pages = DB::Aowow()->selectAssoc('SELECT `type`, `typeId`, COUNT(1) AS "count", MIN(`date`) AS "date" FROM ::screenshots %if', !$all, 'WHERE (`status` & %i) = 0', CC_FLAG_APPROVED | CC_FLAG_DELETED, '%end GROUP BY `type`, `typeId`')) { // limit to one actually existing type each foreach (array_unique(array_column($pages, 'type')) as $t) diff --git a/includes/components/search.class.php b/includes/components/search.class.php index 5818178c..029b864e 100644 --- a/includes/components/search.class.php +++ b/includes/components/search.class.php @@ -80,7 +80,7 @@ class Search private array $included = []; private array $excluded = []; private array $fulltext = []; - private array $cndBase = ['AND']; + private array $cndBase = [DB::AND]; private bool $idSearch = false; public array $invalid = []; @@ -150,7 +150,7 @@ class Search // single cnd? if (count($sub) > 1) - array_unshift($sub, 'AND'); + array_unshift($sub, DB::AND); else $sub = $sub[0]; @@ -159,7 +159,7 @@ class Search // single cnd? if (count($qry) > 1) - array_unshift($qry, 'OR'); + array_unshift($qry, DB::OR); else $qry = $qry[0]; @@ -188,7 +188,7 @@ class Search // single cnd? if (count($qry) > 1) - array_unshift($qry, 'OR'); + array_unshift($qry, DB::OR); else if (count($qry) == 1) $qry = $qry[0]; @@ -349,9 +349,9 @@ class Search { $cnd = array_merge($this->cndBase, array( array( - 'OR', + DB::OR, $this->createLikeLookup(['h.name_loc'.Lang::getLocale()->value]), - ['AND', $this->createLikeLookup(['e.description']), ['e.holidayId', 0]] + [DB::AND, $this->createLikeLookup(['e.description']), ['e.holidayId', 0]] ) )); $wEvents = new WorldEventList($cnd, ['calcTotal' => true]); @@ -1459,7 +1459,7 @@ class Search $cnd = array_merge($this->cndBase, array( ['s.typeCat', -8, '!'], [ - 'OR', + DB::OR, ['s.typeCat', [0, -9]], ['s.cuFlags', SPELL_CU_TRIGGERED, '&'], ['s.attributes0', 0x80, '&'] diff --git a/includes/components/videomgr.class.php b/includes/components/videomgr.class.php index c43ee1fa..1ce894bd 100644 --- a/includes/components/videomgr.class.php +++ b/includes/components/videomgr.class.php @@ -99,20 +99,19 @@ class VideoMgr * unique: bool || null */ - $videos = DB::Aowow()->select( + if ($userId) + $where = [['v.`userIdOwner` = %i', $userId]]; + else + $where = [['v.`type` = %i', $type], ['v.`typeId` = %i', $typeId]]; + + $videos = DB::Aowow()->selectAssoc( 'SELECT v.`id`, a.`username` AS "user", v.`date`, v.`videoId`, v.`type`, v.`typeId`, v.`caption`, v.`status` AS "flags", v.`url`, v.`name` - FROM ?_videos v - LEFT JOIN ?_account a ON v.`userIdOwner` = a.`id` - WHERE - { v.`type` = ?d } - { AND v.`typeId` = ?d } - { v.`userIdOwner` = ?d } - { LIMIT ?d } + FROM ::videos v + LEFT JOIN ::account a ON v.`userIdOwner` = a.`id` + WHERE %and + %lmt ORDER BY `type`, `typeId`, `pos` ASC', - $userId ? DBSIMPLE_SKIP : $type, - $userId ? DBSIMPLE_SKIP : $typeId, - $userId ? $userId : DBSIMPLE_SKIP, - $userId || $type ? DBSIMPLE_SKIP : 100 + $where, $userId || $type ? PHP_INT_MAX : 100 ); $num = []; @@ -176,15 +175,7 @@ class VideoMgr { // i GUESS .. vi_getALL ? everything : pending $nFound = 0; - $pages = DB::Aowow()->select( - 'SELECT v.`type`, v.`typeId`, COUNT(1) AS "count", MIN(v.`date`) AS "date" - FROM ?_videos v - { WHERE (v.`status` & ?d) = 0 } - GROUP BY v.`type`, v.`typeId`', - $all ? DBSIMPLE_SKIP : CC_FLAG_APPROVED | CC_FLAG_DELETED - ); - - if ($pages) + if ($pages = DB::Aowow()->selectAssoc('SELECT `type`, `typeId`, COUNT(1) AS "count", MIN(`date`) AS "date" FROM ::videos %if', !$all, 'WHERE (`status` & %i) = 0', CC_FLAG_APPROVED | CC_FLAG_DELETED, '%end GROUP BY `type`, `typeId`')) { // limit to one actually existing type each foreach (array_unique(array_column($pages, 'type')) as $t) diff --git a/includes/database.class.php b/includes/database.class.php deleted file mode 100644 index 477a17fc..00000000 --- a/includes/database.class.php +++ /dev/null @@ -1,181 +0,0 @@ -<?php - -namespace Aowow; - -if (!defined('AOWOW_REVISION')) - die('illegal access'); - - -class DB -{ - private static array $interfaceCache = []; - private static array $optionsCache = []; - private static array $logs = []; - - private static function createConnectSyntax(array &$options) : string - { - return 'mysqli://'.$options['user'].':'.$options['pass'].'@'.$options['host'].'/'.$options['db']; - } - - public static function connect(int $idx) : void - { - if (self::isConnected($idx)) - { - self::$interfaceCache[$idx]->link->close(); - self::$interfaceCache[$idx] = null; - } - - $options = &self::$optionsCache[$idx]; - $interface = \DbSimple_Generic::connect(self::createConnectSyntax($options)); - - $interface->setErrorHandler(self::errorHandler(...)); - if ($options['prefix']) - $interface->setIdentPrefix($options['prefix']); - - self::$interfaceCache[$idx] = &$interface; - - // should be caught by registered error handler - if (!$interface || !$interface->link) - return; - - $interface->query('SET NAMES ?', 'utf8mb4'); - - // disable STRICT_TRANS_TABLES and STRICT_ALL_TABLES off. It prevents usage of implicit default values. - // disable ONLY_FULL_GROUP_BY (Allows for non-aggregated selects in a group-by query) - $extraModes = ['STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'ONLY_FULL_GROUP_BY', 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE', 'ERROR_FOR_DIVISION_BY_ZERO']; - $oldModes = explode(',', $interface->selectCell('SELECT @@sql_mode')); - $newModes = array_diff($oldModes, $extraModes); - - if ($oldModes != $newModes) - $interface->query("SET SESSION sql_mode = ?", implode(',', $newModes)); - } - - public static function test(array $options, ?string &$err = '') : bool - { - $defPort = ini_get('mysqli.default_port'); - $port = 0; - if (strstr($options['host'], ':')) - [$options['host'], $port] = explode(':', $options['host']); - - if ($link = mysqli_connect($options['host'], $options['user'], $options['pass'], $options['db'], $port ?: $defPort)) - { - mysqli_close($link); - return true; - } - - $err = '['.mysqli_connect_errno().'] '.mysqli_connect_error(); - return false; - } - - public static function errorHandler(string $message, array $data) : void - { - if (!error_reporting()) - return; - - // continue on warning, end on error - $isError = $data['code'] > 0; - - // make number sensible again - $data['code'] = abs($data['code']); - - if (Cfg::get('DEBUG') >= LOG_LEVEL_INFO) - { - echo "\nDB ERROR\n"; - foreach ($data as $k => $v) - echo ' '.str_pad($k.':', 10).$v."\n"; - } - - trigger_error($message, $isError ? E_USER_ERROR : E_USER_WARNING); - } - - public static function profiler(mixed $self, string $query, mixed $trace) : void - { - if ($trace) // actual query - self::$logs[] = [str_replace("\n", ' ', $query)]; - else // the statistics - { - end(self::$logs); - self::$logs[key(self::$logs)][] = substr(explode(';', $query)[0], 5); - } - } - - public static function getProfiles() : string - { - $out = '<pre><table style="font-size:12;"><tr><th></th><th>Time</th><th>Query</th></tr>'; - foreach (self::$logs as $i => [$l, $t]) - { - $c = 'inherit'; - preg_match('/(\d+)/', $t, $m); - if ($m[1] > 100) - $c = '#FFA0A0'; - else if ($m[1] > 20) - $c = '#FFFFA0'; - - $out .= '<tr><td>'.$i.'.</td><td style="background-color:'.$c.';">'.$t.'</td><td>'.$l.'</td></tr>'; - } - - return Util::jsEscape($out).'</table></pre>'; - } - - public static function getDB(int $idx) : ?\DbSimple_Mysqli - { - return self::$interfaceCache[$idx]; - } - - public static function isConnected(int $idx) : bool - { - return isset(self::$interfaceCache[$idx]) && self::$interfaceCache[$idx]->link; - } - - public static function isConnectable(int $idx) : bool - { - return isset(self::$optionsCache[$idx]); - } - - /** - * @static - * @return DbSimple_Mysqli - */ - public static function Characters(int $realmId) : ?\DbSimple_Mysqli - { - if (!isset(self::$optionsCache[DB_CHARACTERS.$realmId])) - die('Connection info not found for live database of realm #'.$realmId.'. Aborted.'); - - return self::getDB(DB_CHARACTERS.$realmId); - } - - /** - * @static - * @return DbSimple_Mysqli - */ - public static function Auth() : ?\DbSimple_Mysqli - { - return self::getDB(DB_AUTH); - } - - /** - * @static - * @return DbSimple_Mysqli - */ - public static function World() : ?\DbSimple_Mysqli - { - return self::getDB(DB_WORLD); - } - - /** - * @static - * @return DbSimple_Mysqli - */ - public static function Aowow() : ?\DbSimple_Mysqli - { - return self::getDB(DB_AOWOW); - } - - public static function load(int $idx, array $config) : void - { - self::$optionsCache[$idx] = $config; - self::connect($idx); - } -} - -?> diff --git a/includes/database.php b/includes/database.php new file mode 100644 index 00000000..f0df4f51 --- /dev/null +++ b/includes/database.php @@ -0,0 +1,332 @@ +<?php + +namespace Aowow; + +if (!defined('AOWOW_REVISION')) + die('illegal access'); + + + +class DibiConnection extends \Dibi\Connection +{ + /** + * Executes SQL query and fetch result - shortcut for query() & fetch(). + */ + public function selectRow(mixed ...$args) : ?array + { + try + { + return (array)$this->query($args)->fetch(); + } + catch (\Exception $e) {} // logged via \Dibi\Event in errorLogger + + return null; + } + + /** + * Executes SQL query and fetch first column - shortcut for query() & fetchSingle(). + */ + public function selectCell(mixed ...$args) : mixed + { + try + { + $x = $this->query($args)->fetchSingle(); + return is_array($x) ? array_pop($x) : $x; + } + catch (\Exception $e) {} // logged via \Dibi\Event in errorLogger + + return null; + } + + /** + * Executes SQL query and fetch first column - shortcut for query() & fetchSingle(). + */ + public function selectCol(mixed ...$args) : ?array + { + try + { + $result = $this->query($args); + if (strpos($args[0], 'ARRAY_KEY2')) + $data = $result->fetchAssoc('ARRAY_KEY|ARRAY_KEY2'); + else if (strpos($args[0], 'ARRAY_KEY')) + $data = $result->fetchAssoc('ARRAY_KEY'); + else + $data = $result->fetchAll(); + + $result->free(); + + // convert Dibi/Row to array + // remove array keys from result set and set result to next cell + array_walk_recursive($data, function(&$row) { + if (get_debug_type($row) == 'Dibi\Row') + $row = (array)$row; + + unset($row['ARRAY_KEY'], $row['ARRAY_KEY2']); + $row = array_pop($row); + }); + return $data; + } + catch (\Exception $e) {} // logged via \Dibi\Event in errorLogger + + return null; + } + + /** + * Executes SQL query and fetch ass associative array + */ + public function selectAssoc(mixed ...$args) : ?array + { + try + { + $result = $this->query($args); + if (strpos($args[0], 'ARRAY_KEY2')) + $data = $result->fetchAssoc('ARRAY_KEY|ARRAY_KEY2'); + else if (strpos($args[0], 'ARRAY_KEY')) + $data = $result->fetchAssoc('ARRAY_KEY'); + else + $data = $result->fetchAll(); + + $result->free(); + + // convert Dibi/Row to array + // remove array keys from result set + array_walk_recursive($data, function(&$row) { + if (get_debug_type($row) == 'Dibi\Row') + $row = (array)$row; + + unset($row['ARRAY_KEY'], $row['ARRAY_KEY2']); + }); + return $data; + } + catch (\Exception $e) {} // logged via \Dibi\Event in errorLogger + + return null; + } + + /** + * Executes SQL query and fetch pairs - shortcut for query() & fetchPairs(). + */ + public function selectPairs(mixed ...$args): ?array + { + try + { + return $this->query($args)->fetchPairs(); + } + catch (\Exception $e) {} // logged via \Dibi\Event in errorLogger + + return null; + } + + /** + * Executes SQL query and returns new insertId or num affected rows. + */ + public function qry(mixed ...$args) : ?int + { + try + { + $this->nativeQuery($this->translate(...$args)); + if (strstr($args[0], 'INSERT')) + return $this->getDriver()?->getResource()?->insert_id; + else + return $this->getAffectedRows(); + } + catch (\Exception $e) {} // logged via \Dibi\Event in errorLogger + + return null; + } +} + +class DB +{ + public const /* string */ AND = '%and'; + public const /* string */ OR = '%or'; + + private static array $interfaceCache = []; + private static array $interfaceTimes = []; + private static array $optionsCache = []; + private static array $logs = []; + + public static function connect(int $idx) : bool + { + if (self::isConnected($idx)) + { + self::$interfaceCache[$idx]->disconnect(); + self::$interfaceCache[$idx] = null; + } + + $config = self::$optionsCache[$idx] + array( + 'charset' => 'utf8mb4', // executes: SET NAMES $charset + 'substitutes' => array( + '' => self::$optionsCache[$idx]['prefix'] // old: ?_ - new: :: + ) + ); + + // alias old DBSimple format + if (empty($config['database']) && !empty($config['db'])) + $config['database'] = &$config['db']; + + try + { + $interface = new DibiConnection($config); + } + catch (\Exception $e) + { + return false; + } + + // disable STRICT_TRANS_TABLES and STRICT_ALL_TABLES. It prevents usage of implicit default values. + // disable ONLY_FULL_GROUP_BY (Allows for non-aggregated selects in a group-by query) + $extraModes = ['STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'ONLY_FULL_GROUP_BY', 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE', 'ERROR_FOR_DIVISION_BY_ZERO']; + $oldModes = explode(',', $interface->fetchSingle('SELECT @@sql_mode')); + $newModes = array_diff($oldModes, $extraModes); + if ($oldModes != $newModes) + $interface->query("SET SESSION sql_mode = %s", implode(',', $newModes)); + + $interface->onEvent[] = self::errorLogger(...); + $interface->onEvent[] = self::profiler(...); + + self::$interfaceCache[$idx] = &$interface; + return true; + } + + public static function test(array $options, ?string &$err = '') : bool + { + $defPort = ini_get('mysqli.default_port'); + $port = 0; + if (strstr($options['host'], ':')) + [$options['host'], $port] = explode(':', $options['host']); + + if ($link = mysqli_connect($options['host'], $options['user'], $options['pass'], $options['db'], $port ?: $defPort)) + { + mysqli_close($link); + return true; + } + + $err = '['.mysqli_connect_errno().'] '.mysqli_connect_error(); + return false; + } + + public static function errorLogger(\Dibi\Event $evt/* string $message, array $data */) : void + { + if (!error_reporting()) + return; + + if (!$evt->result instanceof \Exception) + return; + + $msg = <<<MSG + DB ERROR + code: {$evt->result->getCode()} + message: {$evt->result->getMessage()} + query: {$evt->sql} + context: {$evt->source[0]} line {$evt->source[1]} + MSG; + + if (CLI) + fwrite(STDERR, $msg); + else if (User::isInGroup(U_GROUP_ADMIN) && Cfg::get('DEBUG') >= LOG_LEVEL_INFO) + echo PHP_EOL . '<pre>' . $msg . '</pre>' . PHP_EOL; + + trigger_error($evt->result->getMessage(), E_USER_ERROR); + } + + public static function profiler(\Dibi\Event $evt/* mixed $self, string $query, mixed $trace */) : void + { + $query = \dibi::$sql; + $time = \dibi::$elapsedTime; + + self::$logs[] = [str_replace("\n", ' ', $query), $time]; + } + + public static function getProfiles() : string + { + $out = '<pre><table style="font-size:12;"><tr><th></th><th>Time</th><th>Query</th></tr>'; + foreach (self::$logs as $i => [$l, $t]) + { + // t in seconds + $c = 'inherit'; + if ($t > (100 / 1000)) + $c = '#FFA0A0'; + else if ($t > (20 / 1000)) + $c = '#FFFFA0'; + + $out .= '<tr><td>'.++$i.'.</td><td style="background-color:'.$c.';">'.round($t * 1000, 2).'ms</td><td>'.$l.'</td></tr>'; + } + + $out .= '<tr><td><b>∑t:</b></td><td colspan="2"><b>' . round(array_sum(array_column(self::$logs, 1)) * 1000, 2) . 'ms</b></td></tr>'; + + return Util::jsEscape($out).'</table></pre>'; + } + + public static function load(int $idx, array $config, int $keepAlive = 1 * HOUR) : void + { + self::$optionsCache[$idx] = $config; + if (self::connect($idx)) + self::$interfaceTimes[$idx] = [time() + $keepAlive, $keepAlive]; + } + + public static function isConnected(int $idx) : bool + { + return isset(self::$interfaceCache[$idx]) && self::$interfaceCache[$idx]->isConnected(); + } + + public static function isConnectable(int $idx) : bool + { + return isset(self::$optionsCache[$idx]); + } + + /** + * @static + * @return DibiConnection + */ + public static function Characters(int $realmId) : ?DibiConnection + { + if (!isset(self::$optionsCache[DB_CHARACTERS.$realmId])) + die('Connection info not found for live database of realm #'.$realmId.'. Aborted.'); + + return self::getDB(DB_CHARACTERS.$realmId); + } + + /** + * @static + * @return DibiConnection + */ + public static function Auth() : ?DibiConnection + { + return self::getDB(DB_AUTH); + } + + /** + * @static + * @return DibiConnection + */ + public static function World() : ?DibiConnection + { + return self::getDB(DB_WORLD); + } + + /** + * @static + * @return DibiConnection + */ + public static function Aowow() : ?DibiConnection + { + return self::getDB(DB_AOWOW); + } + + private static function getDB(int $idx) : ?DibiConnection + { + if (self::$interfaceTimes[$idx][0] < time()) + { + self::$interfaceCache[$idx]->disconnect(); + if (!self::connect($idx)) + return null; + + self::$interfaceTimes[$idx][0] = time() + self::$interfaceTimes[$idx][1]; + } + + return self::$interfaceCache[$idx]; + } +} + +?> diff --git a/includes/dbtypes/achievement.class.php b/includes/dbtypes/achievement.class.php index 247aabb0..72b45efc 100644 --- a/includes/dbtypes/achievement.class.php +++ b/includes/dbtypes/achievement.class.php @@ -12,14 +12,14 @@ class AchievementList extends DBTypeList public static int $type = Type::ACHIEVEMENT; public static string $brickFile = 'achievement'; - public static string $dataTable = '?_achievement'; + public static string $dataTable = '::achievement'; public array $criteria = []; - protected string $queryBase = 'SELECT `a`.*, `a`.`id` AS ARRAY_KEY FROM ?_achievement a'; + protected string $queryBase = 'SELECT `a`.*, `a`.`id` AS ARRAY_KEY FROM ::achievement a'; protected array $queryOpts = array( 'a' => [['ic'], 'o' => 'orderInGroup ASC'], - 'ic' => ['j' => ['?_icons ic ON ic.id = a.iconId', true], 's' => ', ic.name AS iconString'], - 'ac' => ['j' => ['?_achievementcriteria AS `ac` ON `ac`.`refAchievementId` = `a`.`id`', true], 'g' => '`a`.`id`'] + 'ic' => ['j' => ['::icons ic ON ic.id = a.iconId', true], 's' => ', ic.name AS iconString'], + 'ac' => ['j' => ['::achievementcriteria AS `ac` ON `ac`.`refAchievementId` = `a`.`id`', true], 'g' => '`a`.`id`'] ); public function __construct(array $conditions = [], array $miscData = []) @@ -30,7 +30,7 @@ class AchievementList extends DBTypeList return; // post processing - $rewards = DB::World()->select( + $rewards = DB::World()->selectAssoc( 'SELECT ar.`ID` AS ARRAY_KEY, ar.`TitleA`, ar.`TitleH`, ar.`ItemID`, ar.`Sender` AS "sender", ar.`MailTemplateID`, ar.`Subject` AS "subject_loc0", IFNULL(arl2.`Subject`, "") AS "subject_loc2", IFNULL(arl3.`Subject`, "") AS "subject_loc3", IFNULL(arl4.`Subject`, "") AS "subject_loc4", IFNULL(arl6.`Subject`, "") AS "subject_loc6", IFNULL(arl8.`Subject`, "") AS "subject_loc8", ar.`Body` AS "text_loc0", IFNULL(arl2.`Body`, "") AS "text_loc2", IFNULL(arl3.`Body`, "") AS "text_loc3", IFNULL(arl4.`Body`, "") AS "text_loc4", IFNULL(arl6.`Body`, "") AS "text_loc6", IFNULL(arl8.`Body`, "") AS "text_loc8" @@ -40,7 +40,7 @@ class AchievementList extends DBTypeList LEFT JOIN achievement_reward_locale arl4 ON arl4.`ID` = ar.`ID` AND arl4.`Locale` = "zhCN" LEFT JOIN achievement_reward_locale arl6 ON arl6.`ID` = ar.`ID` AND arl6.`Locale` = "esES" LEFT JOIN achievement_reward_locale arl8 ON arl8.`ID` = ar.`ID` AND arl8.`Locale` = "ruRU" - WHERE ar.`ID` IN (?a)', + WHERE ar.`ID` IN %in', $this->getFoundIDs() ); @@ -63,7 +63,7 @@ class AchievementList extends DBTypeList // $_curTpl['rewards'][] = [Type::ITEM, $loot['id']]; // lets just assume for now, that mailRewards for achievements do not contain references - $mailRew = DB::World()->selectCol('SELECT `Item` FROM mail_loot_template WHERE `Reference` <= 0 AND `entry` = ?d', $rewards[$_id]['MailTemplateID']); + $mailRew = DB::World()->selectCol('SELECT `Item` FROM mail_loot_template WHERE `Reference` <= 0 AND `entry` = %i', $rewards[$_id]['MailTemplateID']); foreach ($mailRew AS $mr) $_curTpl['rewards'][] = [Type::ITEM, $mr]; } @@ -140,7 +140,7 @@ class AchievementList extends DBTypeList if (isset($this->criteria[$this->id])) return $this->criteria[$this->id]; - $result = DB::Aowow()->Select('SELECT * FROM ?_achievementcriteria WHERE `refAchievementId` = ?d ORDER BY `order` ASC', $this->curTpl['refAchievement'] ?: $this->id); + $result = DB::Aowow()->selectAssoc('SELECT * FROM ::achievementcriteria WHERE `refAchievementId` = %i ORDER BY `order` ASC', $this->curTpl['refAchievement'] ?: $this->id); if (!$result) return []; @@ -381,7 +381,7 @@ class AchievementListFilter extends Filter protected function cbSeries(int $cr, int $crs, string $crv, int $seriesFlag) : ?array { if ($this->int2Bool($crs)) - return $crs ? ['AND', ['chainId', 0, '!'], ['cuFlags', $seriesFlag, '&']] : ['AND', ['chainId', 0, '!'], [['cuFlags', $seriesFlag, '&'], 0]]; + return $crs ? [DB::AND, ['chainId', 0, '!'], ['cuFlags', $seriesFlag, '&']] : [DB::AND, ['chainId', 0, '!'], [['cuFlags', $seriesFlag, '&'], 0]]; return null; } diff --git a/includes/dbtypes/areatrigger.class.php b/includes/dbtypes/areatrigger.class.php index de1fbc19..0012d60e 100644 --- a/includes/dbtypes/areatrigger.class.php +++ b/includes/dbtypes/areatrigger.class.php @@ -12,13 +12,13 @@ class AreaTriggerList extends DBTypeList public static int $type = Type::AREATRIGGER; public static string $brickFile = 'areatrigger'; - public static string $dataTable = '?_areatrigger'; + public static string $dataTable = '::areatrigger'; public static int $contribute = CONTRIBUTE_CO; - protected string $queryBase = 'SELECT a.*, a.id AS ARRAY_KEY FROM ?_areatrigger a'; + protected string $queryBase = 'SELECT a.*, a.id AS ARRAY_KEY FROM ::areatrigger a'; protected array $queryOpts = array( 'a' => [['s']], // guid < 0 are teleporter targets, so exclude them here - 's' => ['j' => ['?_spawns s ON s.`type` = 503 AND s.`typeId` = a.`id` AND s.`guid` > 0', true], 's' => ', GROUP_CONCAT(s.`areaId`) AS "areaId"', 'g' => 'a.`id`'] + 's' => ['j' => ['::spawns s ON s.`type` = 503 AND s.`typeId` = a.`id` AND s.`guid` > 0', true], 's' => ', GROUP_CONCAT(s.`areaId`) AS "areaId"', 'g' => 'a.`id`'] ); public function __construct(array $conditions = [], array $miscData = []) @@ -32,7 +32,7 @@ class AreaTriggerList extends DBTypeList public static function getName(int $id) : ?LocString { - if ($n = DB::Aowow()->SelectRow('SELECT IF(`name`, `name`, CONCAT("Unnamed Areatrigger #", `id`) AS "name_loc0" FROM ?# WHERE `id` = ?d', self::$dataTable, $id)) + if ($n = DB::Aowow()->SelectRow('SELECT IF(`name`, `name`, CONCAT("Unnamed Areatrigger #", `id`) AS "name_loc0" FROM %n WHERE `id` = %i', self::$dataTable, $id)) return new LocString($n); return null; } diff --git a/includes/dbtypes/arenateam.class.php b/includes/dbtypes/arenateam.class.php index a9294093..b50b84fc 100644 --- a/includes/dbtypes/arenateam.class.php +++ b/includes/dbtypes/arenateam.class.php @@ -120,7 +120,7 @@ class RemoteArenaTeamList extends ArenaTeamList // ranks in DB are inaccurate. recalculate from rating (fetched as DESC from DB) foreach ($this->dbNames as $rId => $__) foreach ([2, 3, 5] as $type) - $this->rankOrder[$rId][$type] = DB::Characters($rId)->selectCol('SELECT `arenaTeamId` FROM arena_team WHERE `type` = ?d ORDER BY `rating` DESC', $type); + $this->rankOrder[$rId][$type] = DB::Characters($rId)->selectCol('SELECT `arenaTeamId` FROM arena_team WHERE `type` = %i ORDER BY `rating` DESC', $type); reset($this->dbNames); // only use when querying single realm $realms = Profiler::getRealms(); @@ -168,11 +168,11 @@ class RemoteArenaTeamList extends ArenaTeamList // get team members foreach ($this->members as $realmId => &$teams) - $teams = DB::Characters($realmId)->select( + $teams = DB::Characters($realmId)->selectAssoc( 'SELECT at.`arenaTeamId` AS ARRAY_KEY, c.`guid` AS ARRAY_KEY2, c.`name` AS "0", c.`class` AS "1", IF(at.`captainguid` = c.`guid`, 1, 0) AS "2" FROM arena_team at JOIN arena_team_member atm ON atm.`arenaTeamId` = at.`arenaTeamId` JOIN characters c ON c.`guid` = atm.`guid` - WHERE at.`arenaTeamId` IN (?a) AND c.`deleteInfos_Account` IS NULL AND c.`level` <= ?d AND (c.`extra_flags` & ?d) = 0', + WHERE at.`arenaTeamId` IN %in AND c.`deleteInfos_Account` IS NULL AND c.`level` <= %i AND (c.`extra_flags` & %i) = 0', $teams, MAX_LEVEL, Profiler::CHAR_GMFLAGS ); @@ -228,26 +228,21 @@ class RemoteArenaTeamList extends ArenaTeamList $data = []; foreach ($this->iterate() as $guid => $__) { - $data[$guid] = array( - 'realm' => $this->getField('realm'), - 'realmGUID' => $this->getField('arenaTeamId'), - 'name' => $this->getField('name'), - 'nameUrl' => Profiler::urlize($this->getField('name')), - 'type' => $this->getField('type'), - 'rating' => $this->getField('rating'), - 'stub' => 1 - ); + $data['realm'][$guid] = $this->getField('realm'); + $data['realmGUID'][$guid] = $this->getField('arenaTeamId'); + $data['name'][$guid] = $this->getField('name'); + $data['nameUrl'][$guid] = Profiler::urlize($this->getField('name')); + $data['type'][$guid] = $this->getField('type'); + $data['rating'][$guid] = $this->getField('rating'); + $data['stub'][$guid] = 1; } // basic arena team data - foreach (Util::createSqlBatchInsert($data) as $ins) - DB::Aowow()->query('INSERT INTO ?_profiler_arena_team (?#) VALUES '.$ins.' ON DUPLICATE KEY UPDATE `id` = `id`', array_keys(reset($data))); + DB::Aowow()->qry('INSERT INTO ::profiler_arena_team %m ON DUPLICATE KEY UPDATE `id` = `id`', $data); // merge back local ids - $localIds = DB::Aowow()->selectCol( - 'SELECT CONCAT(`realm`, ":", `realmGUID`) AS ARRAY_KEY, `id` FROM ?_profiler_arena_team WHERE `realm` IN (?a) AND `realmGUID` IN (?a)', - array_column($data, 'realm'), - array_column($data, 'realmGUID') + $localIds = DB::Aowow()->selectCol('SELECT CONCAT(`realm`, ":", `realmGUID`) AS ARRAY_KEY, `id` FROM ::profiler_arena_team WHERE `realm` IN %in AND `realmGUID` IN %in', + $data['realm'], $data['realmGUID'] ); foreach ($this->iterate() as $guid => &$_curTpl) @@ -268,26 +263,24 @@ class RemoteArenaTeamList extends ArenaTeamList foreach ($team as $memberId => $member) { $clearMembers[] = $profiles[$realmId]->getEntry($realmId.':'.$memberId)['id']; - $memberData[] = array( - 'arenaTeamId' => $localIds[$realmId.':'.$teamId], - 'profileId' => $profiles[$realmId]->getEntry($realmId.':'.$memberId)['id'], - 'captain' => $member[2] - ); + + $memberData['arenaTeamId'][] = $localIds[$realmId.':'.$teamId]; + $memberData['profileId'][] = $profiles[$realmId]->getEntry($realmId.':'.$memberId)['id']; + $memberData['captain'][] = $member[2]; } // Delete members from other teams of the same type - DB::Aowow()->query( + DB::Aowow()->qry( 'DELETE atm - FROM ?_profiler_arena_team_member atm - JOIN ?_profiler_arena_team at ON atm.`arenaTeamId` = at.`id` AND at.`type` = ?d - WHERE atm.`profileId` IN (?a)', - $data[$realmId.':'.$teamId]['type'] ?? 0, + FROM ::profiler_arena_team_member atm + JOIN ::profiler_arena_team at ON atm.`arenaTeamId` = at.`id` AND at.`type` = %i + WHERE atm.`profileId` IN %in', + $data['type'][$realmId.':'.$teamId] ?? 0, $clearMembers ); } - foreach (Util::createSqlBatchInsert($memberData) as $ins) - DB::Aowow()->query('INSERT INTO ?_profiler_arena_team_member (?#) VALUES '.$ins.' ON DUPLICATE KEY UPDATE `profileId` = `profileId`', array_keys(reset($memberData))); + DB::Aowow()->qry('INSERT INTO ::profiler_arena_team_member %m ON DUPLICATE KEY UPDATE `profileId` = `profileId`', $memberData); } } } @@ -295,11 +288,11 @@ class RemoteArenaTeamList extends ArenaTeamList class LocalArenaTeamList extends ArenaTeamList { - protected string $queryBase = 'SELECT at.*, at.id AS ARRAY_KEY FROM ?_profiler_arena_team at'; + protected string $queryBase = 'SELECT at.*, at.id AS ARRAY_KEY FROM ::profiler_arena_team at'; protected array $queryOpts = array( 'at' => [['atm', 'c'], 'g' => 'ARRAY_KEY', 'o' => 'rating DESC'], - 'atm' => ['j' => '?_profiler_arena_team_member atm ON atm.`arenaTeamId` = at.`id`'], - 'c' => ['j' => '?_profiler_profiles c ON c.`id` = atm.`profileId`', 's' => ', BIT_OR(IF(c.`race` IN (1, 3, 4, 7, 11), 1, 2)) - 1 AS "faction"'] + 'atm' => ['j' => '::profiler_arena_team_member atm ON atm.`arenaTeamId` = at.`id`'], + 'c' => ['j' => '::profiler_profiles c ON c.`id` = atm.`profileId`', 's' => ', BIT_OR(IF(c.`race` IN (1, 3, 4, 7, 11), 1, 2)) - 1 AS "faction"'] ); public function __construct(array $conditions = [], array $miscData = []) @@ -321,8 +314,8 @@ class LocalArenaTeamList extends ArenaTeamList if ($conditions) { - array_unshift($conditions, 'AND'); - $conditions = ['AND', ['realm', array_keys($realms)], $conditions]; + array_unshift($conditions, DB::AND); + $conditions = [DB::AND, ['realm', array_keys($realms)], $conditions]; } else $conditions = [['realm', array_keys($realms)]]; @@ -333,11 +326,11 @@ class LocalArenaTeamList extends ArenaTeamList return; // post processing - $members = DB::Aowow()->select( + $members = DB::Aowow()->selectAssoc( 'SELECT `arenaTeamId` AS ARRAY_KEY, p.`id` AS ARRAY_KEY2, p.`name` AS "0", p.`class` AS "1", atm.`captain` AS "2" - FROM ?_profiler_arena_team_member atm - JOIN ?_profiler_profiles p ON p.`id` = atm.`profileId` - WHERE `arenaTeamId` IN (?a)', + FROM ::profiler_arena_team_member atm + JOIN ::profiler_profiles p ON p.`id` = atm.`profileId` + WHERE `arenaTeamId` IN %in', $this->getFoundIDs() ); diff --git a/includes/dbtypes/charclass.class.php b/includes/dbtypes/charclass.class.php index 7031ff26..5c6db072 100644 --- a/includes/dbtypes/charclass.class.php +++ b/includes/dbtypes/charclass.class.php @@ -10,12 +10,12 @@ class CharClassList extends DBTypeList { public static int $type = Type::CHR_CLASS; public static string $brickFile = 'class'; - public static string $dataTable = '?_classes'; + public static string $dataTable = '::classes'; - protected string $queryBase = 'SELECT c.*, c.`id` AS ARRAY_KEY FROM ?_classes c'; + protected string $queryBase = 'SELECT c.*, c.`id` AS ARRAY_KEY FROM ::classes c'; protected array $queryOpts = array( 'c' => [['ic']], - 'ic' => ['j' => ['?_icons ic ON ic.`id` = c.`iconId`', true], 's' => ', ic.`name` AS "iconString"'] + 'ic' => ['j' => ['::icons ic ON ic.`id` = c.`iconId`', true], 's' => ', ic.`name` AS "iconString"'] ); public function __construct($conditions = [], array $miscData = []) diff --git a/includes/dbtypes/charrace.class.php b/includes/dbtypes/charrace.class.php index 4117bdbb..c790aafe 100644 --- a/includes/dbtypes/charrace.class.php +++ b/includes/dbtypes/charrace.class.php @@ -10,13 +10,13 @@ class CharRaceList extends DBTypeList { public static int $type = Type::CHR_RACE; public static string $brickFile = 'race'; - public static string $dataTable = '?_races'; + public static string $dataTable = '::races'; - protected string $queryBase = 'SELECT r.*, r.`id` AS ARRAY_KEY FROM ?_races r'; + protected string $queryBase = 'SELECT r.*, r.`id` AS ARRAY_KEY FROM ::races r'; protected array $queryOpts = array( 'r' => [['ic0', 'ic1']], - 'ic0' => ['j' => ['?_icons ic0 ON ic0.`id` = r.`iconId0`', true], 's' => ', ic0.`name` AS "iconStringMale"'], - 'ic1' => ['j' => ['?_icons ic1 ON ic1.`id` = r.`iconId1`', true], 's' => ', ic1.`name` AS "iconStringFemale"'] + 'ic0' => ['j' => ['::icons ic0 ON ic0.`id` = r.`iconId0`', true], 's' => ', ic0.`name` AS "iconStringMale"'], + 'ic1' => ['j' => ['::icons ic1 ON ic1.`id` = r.`iconId1`', true], 's' => ', ic1.`name` AS "iconStringFemale"'] ); public function getListviewData() : array diff --git a/includes/dbtypes/creature.class.php b/includes/dbtypes/creature.class.php index 8c21a7b3..eb51c495 100644 --- a/includes/dbtypes/creature.class.php +++ b/includes/dbtypes/creature.class.php @@ -12,18 +12,18 @@ class CreatureList extends DBTypeList public static int $type = Type::NPC; public static string $brickFile = 'npc'; - public static string $dataTable = '?_creature'; + public static string $dataTable = '::creature'; - protected string $queryBase = 'SELECT ct.*, ct.`id` AS ARRAY_KEY FROM ?_creature ct'; + protected string $queryBase = 'SELECT ct.*, ct.`id` AS ARRAY_KEY FROM ::creature ct'; public array $queryOpts = array( 'ct' => [['ft', 'qse', 'dct1', 'dct2', 'dct3'], 's' => ', IFNULL(dct1.`id`, IFNULL(dct2.`id`, IFNULL(dct3.`id`, 0))) AS "parentId", IFNULL(dct1.`name_loc0`, IFNULL(dct2.`name_loc0`, IFNULL(dct3.`name_loc0`, ""))) AS "parent_loc0", IFNULL(dct1.`name_loc2`, IFNULL(dct2.`name_loc2`, IFNULL(dct3.`name_loc2`, ""))) AS "parent_loc2", IFNULL(dct1.`name_loc3`, IFNULL(dct2.`name_loc3`, IFNULL(dct3.`name_loc3`, ""))) AS "parent_loc3", IFNULL(dct1.`name_loc4`, IFNULL(dct2.`name_loc4`, IFNULL(dct3.`name_loc4`, ""))) AS "parent_loc4", IFNULL(dct1.`name_loc6`, IFNULL(dct2.`name_loc6`, IFNULL(dct3.`name_loc6`, ""))) AS "parent_loc6", IFNULL(dct1.name_loc8, IFNULL(dct2.`name_loc8`, IFNULL(dct3.`name_loc8`, ""))) AS "parent_loc8", IF(dct1.`difficultyEntry1` = ct.`id`, 1, IF(dct2.`difficultyEntry2` = ct.`id`, 2, IF(dct3.`difficultyEntry3` = ct.`id`, 3, 0))) AS "difficultyMode"'], - 'dct1' => ['j' => ['?_creature dct1 ON ct.`cuFlags` & 0x02 AND dct1.`difficultyEntry1` = ct.`id`', true]], - 'dct2' => ['j' => ['?_creature dct2 ON ct.`cuFlags` & 0x02 AND dct2.`difficultyEntry2` = ct.`id`', true]], - 'dct3' => ['j' => ['?_creature dct3 ON ct.`cuFlags` & 0x02 AND dct3.`difficultyEntry3` = ct.`id`', true]], - 'ft' => ['j' => '?_factiontemplate ft ON ft.`id` = ct.`faction`', 's' => ', ft.`factionId`, IFNULL(ft.`A`, 0) AS "A", IFNULL(ft.`H`, 0) AS "H"'], - 'qse' => ['j' => ['?_quests_startend qse ON qse.`type` = 1 AND qse.`typeId` = ct.id', true], 's' => ', IF(MIN(qse.`method`) = 1 OR MAX(qse.`method`) = 3, 1, 0) AS "startsQuests", IF(MIN(qse.`method`) = 2 OR MAX(qse.`method`) = 3, 1, 0) AS "endsQuests"', 'g' => 'ct.`id`'], - 'qt' => ['j' => '?_quests qt ON qse.`questId` = qt.`id`'], - 's' => ['j' => ['?_spawns s ON s.`type` = 1 AND s.`typeId` = ct.`id`', true]] + 'dct1' => ['j' => ['::creature dct1 ON ct.`cuFlags` & 0x02 AND dct1.`difficultyEntry1` = ct.`id`', true]], + 'dct2' => ['j' => ['::creature dct2 ON ct.`cuFlags` & 0x02 AND dct2.`difficultyEntry2` = ct.`id`', true]], + 'dct3' => ['j' => ['::creature dct3 ON ct.`cuFlags` & 0x02 AND dct3.`difficultyEntry3` = ct.`id`', true]], + 'ft' => ['j' => '::factiontemplate ft ON ft.`id` = ct.`faction`', 's' => ', ft.`factionId`, IFNULL(ft.`A`, 0) AS "A", IFNULL(ft.`H`, 0) AS "H"'], + 'qse' => ['j' => ['::quests_startend qse ON qse.`type` = 1 AND qse.`typeId` = ct.id', true], 's' => ', IF(MIN(qse.`method`) = 1 OR MAX(qse.`method`) = 3, 1, 0) AS "startsQuests", IF(MIN(qse.`method`) = 2 OR MAX(qse.`method`) = 3, 1, 0) AS "endsQuests"', 'g' => 'ct.`id`'], + 'qt' => ['j' => '::quests qt ON qse.`questId` = qt.`id`'], + 's' => ['j' => ['::spawns s ON s.`type` = 1 AND s.`typeId` = ct.`id`', true]] ); public function __construct(array $conditions = [], array $miscData = []) @@ -108,7 +108,7 @@ class CreatureList extends DBTypeList $data[] = $_; if (count($data) == 1 && ($slotId = array_search($data[0], $totems))) - $data = DB::World()->selectCol('SELECT `DisplayId` FROM player_totem_model WHERE `TotemSlot` = ?d', $slotId); + $data = DB::World()->selectCol('SELECT `DisplayId` FROM player_totem_model WHERE `TotemSlot` = %i', $slotId); return !$data ? 0 : $data[array_rand($data)]; } @@ -184,8 +184,8 @@ class CreatureList extends DBTypeList if ($addInfoMask & NPCINFO_REP && $this->getFoundIDs()) { $rewRep = DB::World()->selectCol( - 'SELECT `creature_id` AS ARRAY_KEY, `RewOnKillRepFaction1` AS ARRAY_KEY2, `RewOnKillRepValue1` FROM creature_onkill_reputation WHERE `creature_id` IN (?a) AND `RewOnKillRepFaction1` > 0 UNION - SELECT `creature_id` AS ARRAY_KEY, `RewOnKillRepFaction2` AS ARRAY_KEY2, `RewOnKillRepValue2` FROM creature_onkill_reputation WHERE `creature_id` IN (?a) AND `RewOnKillRepFaction2` > 0', + 'SELECT `creature_id` AS ARRAY_KEY, `RewOnKillRepFaction1` AS ARRAY_KEY2, `RewOnKillRepValue1` FROM creature_onkill_reputation WHERE `creature_id` IN %in AND `RewOnKillRepFaction1` > 0 UNION + SELECT `creature_id` AS ARRAY_KEY, `RewOnKillRepFaction2` AS ARRAY_KEY2, `RewOnKillRepValue2` FROM creature_onkill_reputation WHERE `creature_id` IN %in AND `RewOnKillRepFaction2` > 0', $this->getFoundIDs(), $this->getFoundIDs() ); @@ -371,7 +371,7 @@ class CreatureListFilter extends Filter if ($_ = $this->buildMatchLookup(['na' => 'name_loc'.Lang::getLocale()->value])) { if ($parts) - $parts = ['OR', $_, ...$parts]; + $parts = [DB::OR, $_, ...$parts]; else $parts[] = $_; } @@ -422,24 +422,24 @@ class CreatureListFilter extends Filter { if ($crs == parent::ENUM_ANY) { - if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` <> 0')) - if ($cGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_creature WHERE `eventEntry` IN (?a)', $eventIds)) + if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ::events WHERE `holidayId` <> 0')) + if ($cGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_creature WHERE `eventEntry` IN %in', $eventIds)) return ['s.guid', $cGuids]; return [0]; } else if ($crs == parent::ENUM_NONE) { - if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` <> 0')) - if ($cGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_creature WHERE `eventEntry` IN (?a)', $eventIds)) + if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ::events WHERE `holidayId` <> 0')) + if ($cGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_creature WHERE `eventEntry` IN %in', $eventIds)) return ['s.guid', $cGuids, '!']; return [0]; } else if (in_array($crs, self::$enums[$cr])) { - if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` = ?d', $crs)) - if ($cGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM `game_event_creature` WHERE `eventEntry` IN (?a)', $eventIds)) + if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ::events WHERE `holidayId` = %i', $crs)) + if ($cGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM `game_event_creature` WHERE `eventEntry` IN %in', $eventIds)) return ['s.guid', $cGuids]; return [0]; @@ -453,7 +453,7 @@ class CreatureListFilter extends Filter if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs)) return null; - return ['AND', ['((minGold + maxGold) / 2)', $crv, $crs]]; + return [DB::AND, ['((minGold + maxGold) / 2)', $crv, $crs]]; } protected function cbQuestRelation(int $cr, int $crs, string $crv, $field, $val) : ?array @@ -461,13 +461,13 @@ class CreatureListFilter extends Filter switch ($crs) { case 1: // any - return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!']]; + return [DB::AND, ['qse.method', $val, '&'], ['qse.questId', null, '!']]; case 2: // alliance - return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', ChrRace::MASK_HORDE, '&'], 0], ['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&']]; + return [DB::AND, ['qse.method', $val, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', ChrRace::MASK_HORDE, '&'], 0], ['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&']]; case 3: // horde - return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], 0], ['qt.reqRaceMask', ChrRace::MASK_HORDE, '&']]; + return [DB::AND, ['qse.method', $val, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], 0], ['qt.reqRaceMask', ChrRace::MASK_HORDE, '&']]; case 4: // both - return ['AND', ['qse.method', $val, '&'], ['qse.questId', null, '!'], ['OR', ['AND', ['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ['qt.reqRaceMask', ChrRace::MASK_HORDE, '&']], ['qt.reqRaceMask', 0]]]; + return [DB::AND, ['qse.method', $val, '&'], ['qse.questId', null, '!'], [DB::OR, [DB::AND, ['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ['qt.reqRaceMask', ChrRace::MASK_HORDE, '&']], ['qt.reqRaceMask', 0]]]; case 5: // none $this->extraOpts['ct']['h'][] = $field.' = 0'; return [1]; @@ -506,9 +506,9 @@ class CreatureListFilter extends Filter if ($crs) - return ['AND', ['skinLootId', 0, '>'], ['typeFlags', $typeFlag, '&']]; + return [DB::AND, ['skinLootId', 0, '>'], ['typeFlags', $typeFlag, '&']]; else - return ['OR', ['skinLootId', 0], [['typeFlags', $typeFlag, '&'], 0]]; + return [DB::OR, ['skinLootId', 0], [['typeFlags', $typeFlag, '&'], 0]]; } protected function cbRegularSkinLoot(int $cr, int $crs, string $crv, $typeFlag) : ?array @@ -517,9 +517,9 @@ class CreatureListFilter extends Filter return null; if ($crs) - return ['AND', ['skinLootId', 0, '>'], [['typeFlags', $typeFlag, '&'], 0]]; + return [DB::AND, ['skinLootId', 0, '>'], [['typeFlags', $typeFlag, '&'], 0]]; else - return ['OR', ['skinLootId', 0], ['typeFlags', $typeFlag, '&']]; + return [DB::OR, ['skinLootId', 0], ['typeFlags', $typeFlag, '&']]; } protected function cbReputation(int $cr, int $crs, string $crv, $op) : ?array @@ -527,10 +527,10 @@ class CreatureListFilter extends Filter if (!in_array($crs, self::$enums[$cr])) return null; - if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_factions WHERE `id` = ?d', $crs)) + if ($_ = DB::Aowow()->selectRow('SELECT * FROM ::factions WHERE `id` = %i', $crs)) $this->fiReputationCols[] = [$crs, Util::localizedString($_, 'name')]; - if ($cIds = DB::World()->selectCol('SELECT `creature_id` FROM creature_onkill_reputation WHERE (`RewOnKillRepFaction1` = ?d AND `RewOnKillRepValue1` '.$op.' 0) OR (`RewOnKillRepFaction2` = ?d AND `RewOnKillRepValue2` '.$op.' 0)', $crs, $crs)) + if ($cIds = DB::World()->selectCol('SELECT `creature_id` FROM creature_onkill_reputation WHERE (`RewOnKillRepFaction1` = %i AND `RewOnKillRepValue1` '.$op.' 0) OR (`RewOnKillRepFaction2` = %i AND `RewOnKillRepValue2` '.$op.' 0)', $crs, $crs)) return ['id', $cIds]; else return [0]; @@ -545,7 +545,7 @@ class CreatureListFilter extends Filter return null; $facTpls = []; - $facs = new FactionList(array('OR', ['parentFactionId', $crs], ['id', $crs])); + $facs = new FactionList(array(DB::OR, ['parentFactionId', $crs], ['id', $crs])); foreach ($facs->iterate() as $__) $facTpls = array_merge($facTpls, $facs->getField('templateIds')); diff --git a/includes/dbtypes/currency.class.php b/includes/dbtypes/currency.class.php index a5be1df9..79744097 100644 --- a/includes/dbtypes/currency.class.php +++ b/includes/dbtypes/currency.class.php @@ -10,12 +10,12 @@ class CurrencyList extends DBTypeList { public static int $type = Type::CURRENCY; public static string $brickFile = 'currency'; - public static string $dataTable = '?_currencies'; + public static string $dataTable = '::currencies'; - protected string $queryBase = 'SELECT c.*, c.`id` AS ARRAY_KEY FROM ?_currencies c'; + protected string $queryBase = 'SELECT c.*, c.`id` AS ARRAY_KEY FROM ::currencies c'; protected array $queryOpts = array( 'c' => [['ic']], - 'ic' => ['j' => ['?_icons ic ON ic.`id` = c.`iconId`', true], 's' => ', ic.`name` AS "iconString"'] + 'ic' => ['j' => ['::icons ic ON ic.`id` = c.`iconId`', true], 's' => ', ic.`name` AS "iconString"'] ); public function __construct(array $conditions = [], array $miscData = []) diff --git a/includes/dbtypes/emote.class.php b/includes/dbtypes/emote.class.php index 6c9d5a76..3510d687 100644 --- a/includes/dbtypes/emote.class.php +++ b/includes/dbtypes/emote.class.php @@ -10,9 +10,9 @@ class EmoteList extends DBTypeList { public static int $type = Type::EMOTE; public static string $brickFile = 'emote'; - public static string $dataTable = '?_emotes'; + public static string $dataTable = '::emotes'; - protected string $queryBase = 'SELECT e.*, e.`id` AS ARRAY_KEY FROM ?_emotes e'; + protected string $queryBase = 'SELECT e.*, e.`id` AS ARRAY_KEY FROM ::emotes e'; public function __construct(array $conditions = [], array $miscData = []) { @@ -28,7 +28,7 @@ class EmoteList extends DBTypeList public static function getName(int $id) : ?LocString { - if ($n = DB::Aowow()->SelectRow('SELECT `cmd` AS "name_loc0" FROM ?# WHERE `id` = ?d', self::$dataTable, $id)) + if ($n = DB::Aowow()->SelectRow('SELECT `cmd` AS "name_loc0" FROM %n WHERE `id` = %i', self::$dataTable, $id)) return new LocString($n); return null; } diff --git a/includes/dbtypes/enchantment.class.php b/includes/dbtypes/enchantment.class.php index 821e08e8..e3966bc7 100644 --- a/includes/dbtypes/enchantment.class.php +++ b/includes/dbtypes/enchantment.class.php @@ -12,16 +12,16 @@ class EnchantmentList extends DBTypeList public static int $type = Type::ENCHANTMENT; public static string $brickFile = 'enchantment'; - public static string $dataTable = '?_itemenchantment'; + public static string $dataTable = '::itemenchantment'; private array $jsonStats = []; private ?SpellList $relSpells = null; private array $triggerIds = []; - protected string $queryBase = 'SELECT ie.*, ie.id AS ARRAY_KEY FROM ?_itemenchantment ie'; + protected string $queryBase = 'SELECT ie.*, ie.id AS ARRAY_KEY FROM ::itemenchantment ie'; protected array $queryOpts = array( // 502 => Type::ENCHANTMENT 'ie' => [['is']], - 'is' => ['j' => ['?_item_stats `is` ON `is`.`type` = 502 AND `is`.`typeId` = `ie`.`id`', true], 's' => ', `is`.*'], + 'is' => ['j' => ['::item_stats `is` ON `is`.`type` = 502 AND `is`.`typeId` = `ie`.`id`', true], 's' => ', `is`.*'], ); public function __construct(array $conditions = [], array $miscData = []) @@ -63,7 +63,7 @@ class EnchantmentList extends DBTypeList // issue with scaling stats enchantments // stats are stored as NOT NULL to be usable by the search filters and such become indistinguishable from scaling enchantments that _actually_ use the value 0 - // so we can't rely on ?_item_stats and always have to calc stats + // so we can't rely on ::item_stats and always have to calc stats foreach ($this->iterate() as $ench) { $relSpells = []; @@ -254,7 +254,7 @@ class EnchantmentListFilter extends Filter // type if ($_v['ty']) - $parts[] = ['OR', ['type1', $_v['ty']], ['type2', $_v['ty']], ['type3', $_v['ty']]]; + $parts[] = [DB::OR, ['type1', $_v['ty']], ['type2', $_v['ty']], ['type3', $_v['ty']]]; return $parts; } diff --git a/includes/dbtypes/faction.class.php b/includes/dbtypes/faction.class.php index 6e0b4d1b..cf76280d 100644 --- a/includes/dbtypes/faction.class.php +++ b/includes/dbtypes/faction.class.php @@ -10,13 +10,13 @@ class FactionList extends DBTypeList { public static int $type = Type::FACTION; public static string $brickFile = 'faction'; - public static string $dataTable = '?_factions'; + public static string $dataTable = '::factions'; - protected string $queryBase = 'SELECT f.*, f.`parentFactionId` AS "cat", f.`id` AS ARRAY_KEY FROM ?_factions f'; + protected string $queryBase = 'SELECT f.*, f.`parentFactionId` AS "cat", f.`id` AS ARRAY_KEY FROM ::factions f'; protected array $queryOpts = array( 'f' => [['f2']], - 'f2' => ['j' => ['?_factions f2 ON f.`parentFactionId` = f2.`id`', true], 's' => ', IFNULL(f2.`parentFactionId`, 0) AS "cat2"'], - 'ft' => ['j' => '?_factiontemplate ft ON ft.`factionId` = f.`id`'] + 'f2' => ['j' => ['::factions f2 ON f.`parentFactionId` = f2.`id`', true], 's' => ', IFNULL(f2.`parentFactionId`, 0) AS "cat2"'], + 'ft' => ['j' => '::factiontemplate ft ON ft.`factionId` = f.`id`'] ); public function __construct(array $conditions = [], array $miscData = []) diff --git a/includes/dbtypes/gameobject.class.php b/includes/dbtypes/gameobject.class.php index b15f8393..e37b0a9d 100644 --- a/includes/dbtypes/gameobject.class.php +++ b/includes/dbtypes/gameobject.class.php @@ -12,15 +12,15 @@ class GameObjectList extends DBTypeList public static int $type = Type::OBJECT; public static string $brickFile = 'object'; - public static string $dataTable = '?_objects'; + public static string $dataTable = '::objects'; - protected string $queryBase = 'SELECT o.*, o.`id` AS ARRAY_KEY FROM ?_objects o'; + protected string $queryBase = 'SELECT o.*, o.`id` AS ARRAY_KEY FROM ::objects o'; protected array $queryOpts = array( 'o' => [['ft', 'qse']], - 'ft' => ['j' => ['?_factiontemplate ft ON ft.`id` = o.`faction`', true], 's' => ', ft.`factionId`, IFNULL(ft.`A`, 0) AS "A", IFNULL(ft.`H`, 0) AS "H"'], - 'qse' => ['j' => ['?_quests_startend qse ON qse.`type` = 2 AND qse.`typeId` = o.id', true], 's' => ', IF(MIN(qse.`method`) = 1 OR MAX(qse.`method`) = 3, 1, 0) AS "startsQuests", IF(MIN(qse.`method`) = 2 OR MAX(qse.`method`) = 3, 1, 0) AS "endsQuests"', 'g' => 'o.`id`'], - 'qt' => ['j' => '?_quests qt ON qse.`questId` = qt.`id`'], - 's' => ['j' => '?_spawns s ON s.`type` = 2 AND s.`typeId` = o.`id`'] + 'ft' => ['j' => ['::factiontemplate ft ON ft.`id` = o.`faction`', true], 's' => ', ft.`factionId`, IFNULL(ft.`A`, 0) AS "A", IFNULL(ft.`H`, 0) AS "H"'], + 'qse' => ['j' => ['::quests_startend qse ON qse.`type` = 2 AND qse.`typeId` = o.id', true], 's' => ', IF(MIN(qse.`method`) = 1 OR MAX(qse.`method`) = 3, 1, 0) AS "startsQuests", IF(MIN(qse.`method`) = 2 OR MAX(qse.`method`) = 3, 1, 0) AS "endsQuests"', 'g' => 'o.`id`'], + 'qt' => ['j' => '::quests qt ON qse.`questId` = qt.`id`'], + 's' => ['j' => '::spawns s ON s.`type` = 2 AND s.`typeId` = o.`id`'] ); public function __construct(array $conditions = [], array $miscData = []) @@ -189,7 +189,7 @@ class GameObjectListFilter extends Filter protected function cbOpenable(int $cr, int $crs, string $crv) : ?array { if ($this->int2Bool($crs)) - return $crs ? ['OR', ['flags', 0x2, '&'], ['type', 3]] : ['AND', [['flags', 0x2, '&'], 0], ['type', 3, '!']]; + return $crs ? [DB::OR, ['flags', 0x2, '&'], ['type', 3]] : [DB::AND, [['flags', 0x2, '&'], 0], ['type', 3, '!']]; return null; } @@ -199,13 +199,13 @@ class GameObjectListFilter extends Filter switch ($crs) { case 1: // any - return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!']]; + return [DB::AND, ['qse.method', $value, '&'], ['qse.questId', null, '!']]; case 2: // alliance only - return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', ChrRace::MASK_HORDE, '&'], 0], ['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&']]; + return [DB::AND, ['qse.method', $value, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', ChrRace::MASK_HORDE, '&'], 0], ['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&']]; case 3: // horde only - return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], 0], ['qt.reqRaceMask', ChrRace::MASK_HORDE, '&']]; + return [DB::AND, ['qse.method', $value, '&'], ['qse.questId', null, '!'], [['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], 0], ['qt.reqRaceMask', ChrRace::MASK_HORDE, '&']]; case 4: // both - return ['AND', ['qse.method', $value, '&'], ['qse.questId', null, '!'], ['OR', ['AND', ['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ['qt.reqRaceMask', ChrRace::MASK_HORDE, '&']], ['qt.reqRaceMask', 0]]]; + return [DB::AND, ['qse.method', $value, '&'], ['qse.questId', null, '!'], [DB::OR, [DB::AND, ['qt.reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ['qt.reqRaceMask', ChrRace::MASK_HORDE, '&']], ['qt.reqRaceMask', 0]]]; case 5: // none todo (low): broken, if entry starts and ends quests... $this->extraOpts['o']['h'][] = $field.' = 0'; return [1]; @@ -218,24 +218,24 @@ class GameObjectListFilter extends Filter { if ($crs == parent::ENUM_ANY) { - if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` <> 0')) - if ($goGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_gameobject WHERE `eventEntry` IN (?a)', $eventIds)) + if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ::events WHERE `holidayId` <> 0')) + if ($goGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_gameobject WHERE `eventEntry` IN %in', $eventIds)) return ['s.guid', $goGuids]; return [0]; } else if ($crs == parent::ENUM_NONE) { - if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` <> 0')) - if ($goGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_gameobject WHERE `eventEntry` IN (?a)', $eventIds)) + if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ::events WHERE `holidayId` <> 0')) + if ($goGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_gameobject WHERE `eventEntry` IN %in', $eventIds)) return ['s.guid', $goGuids, '!']; return [0]; } else if (in_array($crs, self::$enums[$cr])) { - if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ?_events WHERE `holidayId` = ?d', $crs)) - if ($goGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_gameobject WHERE `eventEntry` IN (?a)', $eventIds)) + if ($eventIds = DB::Aowow()->selectCol('SELECT `id` FROM ::events WHERE `holidayId` = %i', $crs)) + if ($goGuids = DB::World()->selectCol('SELECT DISTINCT `guid` FROM game_event_gameobject WHERE `eventEntry` IN %in', $eventIds)) return ['s.guid', $goGuids]; return [0]; diff --git a/includes/dbtypes/guide.class.php b/includes/dbtypes/guide.class.php index 492b47a0..d1cc5f5c 100644 --- a/includes/dbtypes/guide.class.php +++ b/includes/dbtypes/guide.class.php @@ -12,18 +12,18 @@ class GuideList extends DBTypeList public static int $type = Type::GUIDE; public static string $brickFile = 'guide'; - public static string $dataTable = '?_guides'; + public static string $dataTable = '::guides'; public static int $contribute = CONTRIBUTE_CO; private array $article = []; private array $jsGlobals = []; - protected string $queryBase = 'SELECT g.*, g.`id` AS ARRAY_KEY FROM ?_guides g'; + protected string $queryBase = 'SELECT g.*, g.`id` AS ARRAY_KEY FROM ::guides g'; protected array $queryOpts = array( 'g' => [['a', 'c', 'ar'], 'g' => 'g.`id`'], - 'a' => ['j' => ['?_account a ON a.`id` = g.`userId`', true], 's' => ', IFNULL(a.`username`, "") AS "author"'], - 'c' => ['j' => ['?_comments c ON c.`type` = '.Type::GUIDE.' AND c.`typeId` = g.`id` AND (c.`flags` & '.CC_FLAG_DELETED.') = 0', true], 's' => ', COUNT(c.`id`) AS "comments"'], - 'ar' => ['j' => ['?_articles ar ON ar.`type` = 300 AND ar.`typeId` = g.`id`'], 's' => ', MAX(ar.`rev`) AS "latest"'] + 'a' => ['j' => ['::account a ON a.`id` = g.`userId`', true], 's' => ', IFNULL(a.`username`, "") AS "author"'], + 'c' => ['j' => ['::comments c ON c.`type` = '.Type::GUIDE.' AND c.`typeId` = g.`id` AND (c.`flags` & '.CC_FLAG_DELETED.') = 0', true], 's' => ', COUNT(c.`id`) AS "comments"'], + 'ar' => ['j' => ['::articles ar ON ar.`type` = 300 AND ar.`typeId` = g.`id`'], 's' => ', MAX(ar.`rev`) AS "latest"'] ); public function __construct(array $conditions = [], array $miscData = []) @@ -42,7 +42,7 @@ class GuideList extends DBTypeList public static function getName(int $id) : ?LocString { - if ($n = DB::Aowow()->SelectRow('SELECT `title` AS "name_loc0" FROM ?# WHERE `id` = ?d', self::$dataTable, $id)) + if ($n = DB::Aowow()->SelectRow('SELECT `title` AS "name_loc0" FROM %n WHERE `id` = %i', self::$dataTable, $id)) return new LocString($n); return null; } @@ -54,8 +54,15 @@ class GuideList extends DBTypeList if (empty($this->article[$rev])) { - $a = DB::Aowow()->selectRow('SELECT `article`, `rev` FROM ?_articles WHERE ((`type` = ?d AND `typeId` = ?d){ OR `url` = ?}){ AND `rev`= ?d} ORDER BY `rev` DESC LIMIT 1', - Type::GUIDE, $this->id, $this->getField('url') ?: DBSIMPLE_SKIP, $rev < 0 ? DBSIMPLE_SKIP : $rev); + $where = array( + [DB::OR, [[DB::AND, [['`type` = %i', Type::GUIDE], ['`typeId` = %i', $this->id]]]]] + ); + if ($url = $this->getField('url')) + $where[0][1][] = ['`url` = %s', $url]; + if ($rev >= 0) + $where[] = ['`rev`= %i', $rev]; + + $a = DB::Aowow()->selectRow('SELECT `article`, `rev` FROM ::articles WHERE %and ORDER BY `rev` DESC LIMIT 1', $where); $this->article[$a['rev']] = $a['article']; if ($this->article[$a['rev']]) diff --git a/includes/dbtypes/guild.class.php b/includes/dbtypes/guild.class.php index 0732a404..93a59211 100644 --- a/includes/dbtypes/guild.class.php +++ b/includes/dbtypes/guild.class.php @@ -48,7 +48,7 @@ class GuildList extends DBTypeList if (!$guilds) return; - $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); + $stats = DB::Aowow()->selectAssoc('SELECT `guild` AS ARRAY_KEY, `id` AS ARRAY_KEY2, `level`, `gearscore`, `achievementpoints` FROM ::profiler_profiles WHERE `guild` IN %in AND `stub` = 0 ORDER BY `gearscore` DESC', $guilds); foreach ($this->iterate() as &$_curTpl) { $id = $_curTpl['id']; @@ -218,27 +218,25 @@ class RemoteGuildList extends GuildList public function initializeLocalEntries() : void { + if (!$this->templates) + return; + $data = []; foreach ($this->iterate() as $guid => $__) { - $data[$guid] = array( - 'realm' => $this->getField('realm'), - 'realmGUID' => $this->getField('guildid'), - 'name' => $this->getField('name'), - 'nameUrl' => Profiler::urlize($this->getField('name')), - 'stub' => 1 - ); + $data['realm'][$guid] = $this->getField('realm'); + $data['realmGUID'][$guid] = $this->getField('guildid'); + $data['name'][$guid] = $this->getField('name'); + $data['nameUrl'][$guid] = Profiler::urlize($this->getField('name')); + $data['stub'][$guid] = 1; } // basic guild data - foreach (Util::createSqlBatchInsert($data) as $ins) - DB::Aowow()->query('INSERT INTO ?_profiler_guild (?#) VALUES '.$ins.' ON DUPLICATE KEY UPDATE `id` = `id`', array_keys(reset($data))); + DB::Aowow()->qry('INSERT INTO ::profiler_guild %m ON DUPLICATE KEY UPDATE `id` = `id`', $data); // merge back local ids - $localIds = DB::Aowow()->selectCol( - 'SELECT CONCAT(`realm`, ":", `realmGUID`) AS ARRAY_KEY, `id` FROM ?_profiler_guild WHERE `realm` IN (?a) AND `realmGUID` IN (?a)', - array_column($data, 'realm'), - array_column($data, 'realmGUID') + $localIds = DB::Aowow()->selectCol('SELECT CONCAT(`realm`, ":", `realmGUID`) AS ARRAY_KEY, `id` FROM ::profiler_guild WHERE `realm` IN %in AND `realmGUID` IN %in', + $data['realm'], $data['realmGUID'] ); foreach ($this->iterate() as $guid => &$_curTpl) @@ -250,7 +248,7 @@ class RemoteGuildList extends GuildList class LocalGuildList extends GuildList { - protected string $queryBase = 'SELECT g.*, g.`id` AS ARRAY_KEY FROM ?_profiler_guild g'; + protected string $queryBase = 'SELECT g.*, g.`id` AS ARRAY_KEY FROM ::profiler_guild g'; public function __construct(array $conditions = [], array $miscData = []) { @@ -271,8 +269,8 @@ class LocalGuildList extends GuildList if ($conditions) { - array_unshift($conditions, 'AND'); - $conditions = ['AND', ['realm', array_keys($realms)], $conditions]; + array_unshift($conditions, DB::AND); + $conditions = [DB::AND, ['realm', array_keys($realms)], $conditions]; } else $conditions = [['realm', array_keys($realms)]]; diff --git a/includes/dbtypes/icon.class.php b/includes/dbtypes/icon.class.php index 455bd303..a48764f3 100644 --- a/includes/dbtypes/icon.class.php +++ b/includes/dbtypes/icon.class.php @@ -12,27 +12,27 @@ class IconList extends DBTypeList public static int $type = Type::ICON; public static string $brickFile = 'icongallery'; - public static string $dataTable = '?_icons'; + public static string $dataTable = '::icons'; public static int $contribute = CONTRIBUTE_CO; - private string $pseudoQry = 'SELECT `iconId` AS ARRAY_KEY, COUNT(*) FROM ?# WHERE `iconId` IN (?a) GROUP BY `iconId`'; + private string $pseudoQry = 'SELECT `iconId` AS ARRAY_KEY, COUNT(*) FROM %n WHERE `iconId` IN %in GROUP BY `iconId`'; private array $pseudoJoin = array( - 'nItems' => '?_items', - 'nSpells' => '?_spell', - 'nAchievements' => '?_achievement', - 'nCurrencies' => '?_currencies', - 'nPets' => '?_pet' + 'nItems' => '::items', + 'nSpells' => '::spell', + 'nAchievements' => '::achievement', + 'nCurrencies' => '::currencies', + 'nPets' => '::pet' ); - protected string $queryBase = 'SELECT ic.*, ic.`id` AS ARRAY_KEY FROM ?_icons ic'; + protected string $queryBase = 'SELECT ic.*, ic.`id` AS ARRAY_KEY FROM ::icons ic'; /* this works, but takes ~100x more time than i'm comfortable with .. kept as reference protected array $queryOpts = array( // 29 => Type::ICON 'ic' => [['s', 'i', 'a', 'c', 'p'], 'g' => 'ic.id'], - 'i' => ['j' => ['?_items `i` ON `i`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `i`.`id`) AS "nItems"'], - 's' => ['j' => ['?_spell `s` ON `s`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `s`.`id`) AS "nSpells"'], - 'a' => ['j' => ['?_achievement `a` ON `a`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `a`.`id`) AS "nAchievements"'], - 'c' => ['j' => ['?_currencies `c` ON `c`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `c`.`id`) AS "nCurrencies"'], - 'p' => ['j' => ['?_pet `p` ON `p`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `p`.`id`) AS "nPets"'] + 'i' => ['j' => ['::items `i` ON `i`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `i`.`id`) AS "nItems"'], + 's' => ['j' => ['::spell `s` ON `s`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `s`.`id`) AS "nSpells"'], + 'a' => ['j' => ['::achievement `a` ON `a`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `a`.`id`) AS "nAchievements"'], + 'c' => ['j' => ['::currencies `c` ON `c`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `c`.`id`) AS "nCurrencies"'], + 'p' => ['j' => ['::pet `p` ON `p`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `p`.`id`) AS "nPets"'] ); */ @@ -53,7 +53,7 @@ class IconList extends DBTypeList public static function getName(int $id) : ?LocString { - if ($n = DB::Aowow()->selectRow('SELECT `name` AS "name_loc0" FROM ?# WHERE `id` = ?d', self::$dataTable, $id)) + if ($n = DB::Aowow()->selectRow('SELECT `name` AS "name_loc0" FROM %n WHERE `id` = %i', self::$dataTable, $id)) return new LocString($n); return null; } @@ -103,17 +103,17 @@ class IconListFilter extends Filter { private array $iconTotals = []; private array $criterion2field = array( - 1 => '?_items', // items [num] - 2 => '?_spell', // spells [num] - 3 => '?_achievement', // achievements [num] + 1 => '::items', // items [num] + 2 => '::spell', // spells [num] + 3 => '::achievement', // achievements [num] // 4 => '', // battlepets [num] // 5 => '', // battlepetabilities [num] - 6 => '?_currencies', // currencies [num] + 6 => '::currencies', // currencies [num] // 7 => '', // garrisonabilities [num] // 8 => '', // garrisonbuildings [num] - 9 => '?_pet', // hunterpets [num] + 9 => '::pet', // hunterpets [num] // 10 => '', // garrisonmissionthreats [num] - 11 => '?_classes', // classes [num] + 11 => '::classes', // classes [num] 13 => '' // used [num] ); @@ -186,7 +186,7 @@ class IconListFilter extends Filter if (!$tbl || isset($this->iconTotals[$cr]) || ($forCr && $forCr != $cr)) continue; - $this->iconTotals[$cr] = DB::Aowow()->selectCol('SELECT `iconId` AS ARRAY_KEY, COUNT(*) AS "n" FROM ?# GROUP BY `iconId`', $tbl); + $this->iconTotals[$cr] = DB::Aowow()->selectCol('SELECT `iconId` AS ARRAY_KEY, COUNT(*) AS "n" FROM %n GROUP BY `iconId`', $tbl); } if ($forCr) diff --git a/includes/dbtypes/item.class.php b/includes/dbtypes/item.class.php index 7d075ef0..ba543d82 100644 --- a/includes/dbtypes/item.class.php +++ b/includes/dbtypes/item.class.php @@ -12,7 +12,7 @@ class ItemList extends DBTypeList public static int $type = Type::ITEM; public static string $brickFile = 'item'; - public static string $dataTable = '?_items'; + public static string $dataTable = '::items'; public array $json = []; public array $jsonStats = []; public array $rndEnchIds = []; @@ -25,14 +25,14 @@ class ItemList extends DBTypeList private array $enhanceR = []; private array $relEnchant = []; - protected string $queryBase = 'SELECT i.*, i.`block` AS "tplBlock", i.`armor` AS tplArmor, i.`dmgMin1` AS "tplDmgMin1", i.`dmgMax1` AS "tplDmgMax1", i.`id` AS ARRAY_KEY, i.`id` AS "id" FROM ?_items i'; + protected string $queryBase = 'SELECT i.*, i.`block` AS "tplBlock", i.`armor` AS tplArmor, i.`dmgMin1` AS "tplDmgMin1", i.`dmgMax1` AS "tplDmgMax1", i.`id` AS ARRAY_KEY, i.`id` AS "id" FROM ::items i'; protected array $queryOpts = array( // 3 => Type::ITEM 'i' => [['is', 'src', 'ic'], 'o' => 'i.`quality` DESC, i.`itemLevel` DESC'], - 'ic' => ['j' => ['?_icons `ic` ON `ic`.`id` = `i`.`iconId`', true], 's' => ', ic.`name` AS "iconString"'], - 'is' => ['j' => ['?_item_stats `is` ON `is`.`type` = 3 AND `is`.`typeId` = `i`.`id`', true], 's' => ', `is`.*'], - 's' => ['j' => ['?_spell `s` ON `s`.`effect1CreateItemId` = `i`.`id`', true], 'g' => 'i.`id`'], - 'e' => ['j' => ['?_events `e` ON `e`.`id` = `i`.`eventId`', true], 's' => ', e.`holidayId`'], - 'src' => ['j' => ['?_source `src` ON `src`.`type` = 3 AND `src`.`typeId` = `i`.`id`', true], 's' => ', `moreType`, `moreTypeId`, `moreZoneId`, `moreMask`, `src1`, `src2`, `src3`, `src4`, `src5`, `src6`, `src7`, `src8`, `src9`, `src10`, `src11`, `src12`, `src13`, `src14`, `src15`, `src16`, `src17`, `src18`, `src19`, `src20`, `src21`, `src22`, `src23`, `src24`'] + 'ic' => ['j' => ['::icons `ic` ON `ic`.`id` = `i`.`iconId`', true], 's' => ', ic.`name` AS "iconString"'], + 'is' => ['j' => ['::item_stats `is` ON `is`.`type` = 3 AND `is`.`typeId` = `i`.`id`', true], 's' => ', `is`.*'], + 's' => ['j' => ['::spell `s` ON `s`.`effect1CreateItemId` = `i`.`id`', true], 'g' => 'i.`id`'], + 'e' => ['j' => ['::events `e` ON `e`.`id` = `i`.`eventId`', true], 's' => ', e.`holidayId`'], + 'src' => ['j' => ['::source `src` ON `src`.`type` = 3 AND `src`.`typeId` = `i`.`id`', true], 's' => ', `moreType`, `moreTypeId`, `moreZoneId`, `moreMask`, `src1`, `src2`, `src3`, `src4`, `src5`, `src6`, `src7`, `src8`, `src9`, `src10`, `src11`, `src12`, `src13`, `src14`, `src15`, `src16`, `src17`, `src18`, `src19`, `src20`, `src21`, `src22`, `src23`, `src24`'] ); public function __construct(array $conditions = [], array $miscData = []) @@ -85,29 +85,28 @@ class ItemList extends DBTypeList if (empty($this->vendors)) { + $itemIds = array_keys($this->templates); + if (!empty($filter[Type::NPC]) && is_array($filter[Type::NPC])) + $itemIds = array_intersect($itemIds, $filter[Type::NPC]); + $itemz = []; $xCostData = []; - $rawEntries = DB::World()->select( - 'SELECT nv.`item`, nv.`entry`, 0 AS "eventId", nv.`maxcount`, nv.`extendedCost`, nv.`incrtime` + $rawEntries = DB::World()->selectAssoc( + 'SELECT nv.`item`, nv.`entry`, 0 AS "eventId", nv.`maxcount`, nv.`extendedCost`, nv.`incrtime` FROM npc_vendor nv - WHERE { nv.`entry` IN (?a) AND } nv.`item` IN (?a) + WHERE nv.`item` IN %in UNION - SELECT nv2.`item`, nv1.`entry`, 0 AS "eventId", nv2.`maxcount`, nv2.`extendedCost`, nv2.`incrtime` + SELECT nv2.`item`, nv1.`entry`, 0 AS "eventId", nv2.`maxcount`, nv2.`extendedCost`, nv2.`incrtime` FROM npc_vendor nv1 - JOIN npc_vendor nv2 ON -nv1.`item` = nv2.`entry` { AND nv1.`entry` IN (?a) } - WHERE nv2.`item` IN (?a) + JOIN npc_vendor nv2 ON -nv1.`item` = nv2.`entry` + WHERE nv2.`item` IN %in UNION - SELECT genv.`item`, c.`id` AS "entry", ge.`eventEntry` AS "eventId", genv.`maxcount`, genv.`extendedCost`, genv.`incrtime` + SELECT genv.`item`, c.`id` AS "entry", ge.`eventEntry` AS "eventId", genv.`maxcount`, genv.`extendedCost`, genv.`incrtime` FROM game_event_npc_vendor genv LEFT JOIN game_event ge ON genv.`eventEntry` = ge.`eventEntry` JOIN creature c ON c.`guid` = genv.`guid` - WHERE { c.`id` IN (?a) AND } genv.`item` IN (?a)', - empty($filter[Type::NPC]) || !is_array($filter[Type::NPC]) ? DBSIMPLE_SKIP : $filter[Type::NPC], - array_keys($this->templates), - empty($filter[Type::NPC]) || !is_array($filter[Type::NPC]) ? DBSIMPLE_SKIP : $filter[Type::NPC], - array_keys($this->templates), - empty($filter[Type::NPC]) || !is_array($filter[Type::NPC]) ? DBSIMPLE_SKIP : $filter[Type::NPC], - array_keys($this->templates) + WHERE genv.`item` IN %in', + $itemIds, $itemIds, $itemIds ); foreach ($rawEntries as $costEntry) @@ -122,7 +121,7 @@ class ItemList extends DBTypeList } if ($xCostData) - $xCostData = DB::Aowow()->select('SELECT *, `id` AS ARRAY_KEY FROM ?_itemextendedcost WHERE `id` IN (?a)', $xCostData); + $xCostData = DB::Aowow()->selectAssoc('SELECT *, `id` AS ARRAY_KEY FROM ::itemextendedcost WHERE `id` IN %in', $xCostData); $cItems = []; foreach ($itemz as $k => $vendors) @@ -540,7 +539,7 @@ class ItemList extends DBTypeList if ($this->enhanceR['enchantId'.$i] <= 0) continue; - $enchant = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE `id` = ?d', $this->enhanceR['enchantId'.$i]); + $enchant = DB::Aowow()->selectRow('SELECT * FROM ::itemenchantment WHERE `id` = %i', $this->enhanceR['enchantId'.$i]); if ($this->enhanceR['allocationPct'.$i] > 0) { $amount = intVal($this->enhanceR['allocationPct'.$i] * $this->generateEnchSuffixFactor()); @@ -574,17 +573,17 @@ class ItemList extends DBTypeList if (($_flags & ITEM_FLAG_HEROIC) && $_quality == ITEM_QUALITY_EPIC) $x .= '<br /><span class="q2">'.Lang::item('heroic').'</span>'; - // requires map (todo: reparse ?_zones for non-conflicting data; generate Link to zone) + // requires map (todo: reparse :zones for non-conflicting data; generate Link to zone) if ($_ = $this->curTpl['map']) { - $map = DB::Aowow()->selectRow('SELECT * FROM ?_zones WHERE `mapId` = ?d LIMIT 1', $_); + $map = DB::Aowow()->selectRow('SELECT * FROM ::zones WHERE `mapId` = %i LIMIT 1', $_); $x .= '<br /><a href="?zone='.$_.'" class="q1">'.Util::localizedString($map, 'name').'</a>'; } // requires area if ($this->curTpl['area']) { - $area = DB::Aowow()->selectRow('SELECT * FROM ?_zones WHERE `id` = ?d LIMIT 1', $this->curTpl['area']); + $area = DB::Aowow()->selectRow('SELECT * FROM ::zones WHERE `id` = %i LIMIT 1', $this->curTpl['area']); $x .= '<br />'.Util::localizedString($area, 'name'); } @@ -608,13 +607,13 @@ class ItemList extends DBTypeList $x .= '<br />'.Lang::item('uniqueEquipped', 0); else if ($this->curTpl['itemLimitCategory']) { - $limit = DB::Aowow()->selectRow("SELECT * FROM ?_itemlimitcategory WHERE `id` = ?", $this->curTpl['itemLimitCategory']); + $limit = DB::Aowow()->selectRow('SELECT * FROM ::itemlimitcategory WHERE `id` = %i', $this->curTpl['itemLimitCategory']); $x .= '<br />'.sprintf(Lang::item($limit['isGem'] ? 'uniqueEquipped' : 'unique', 2), Util::localizedString($limit, 'name'), $limit['count']); } // required holiday if ($eId = $this->curTpl['eventId']) - if ($hName = DB::Aowow()->selectRow('SELECT h.* FROM ?_holidays h JOIN ?_events e ON e.`holidayId` = h.`id` WHERE e.`id` = ?d', $eId)) + if ($hName = DB::Aowow()->selectRow('SELECT h.* FROM ::holidays h JOIN ::events e ON e.`holidayId` = h.`id` WHERE e.`id` = %i', $eId)) $x .= '<br />'.sprintf(Lang::game('requires'), '<a href="?event='.$eId.'" class="q1">'.Util::localizedString($hName, 'name').'</a>'); // item begins a quest @@ -711,7 +710,7 @@ class ItemList extends DBTypeList // Item is a gem (don't mix with sockets) if ($geId = $this->curTpl['gemEnchantmentId']) { - $gemEnch = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE `id` = ?d', $geId); + $gemEnch = DB::Aowow()->selectRow('SELECT * FROM ::itemenchantment WHERE `id` = %i', $geId); $x .= '<span class="q1"><a href="?enchantment='.$geId.'">'.Util::localizedString($gemEnch, 'name').'</a></span><br />'; // activation conditions for meta gems @@ -768,7 +767,7 @@ class ItemList extends DBTypeList // Enchantment if (isset($enhance['e'])) { - if ($enchText = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE `id` = ?', $enhance['e'])) + if ($enchText = DB::Aowow()->selectRow('SELECT * FROM ::itemenchantment WHERE `id` = %s', $enhance['e'])) $x .= '<span class="q2"><!--e-->'.Util::localizedString($enchText, 'name').'</span><br />'; else { @@ -782,12 +781,12 @@ class ItemList extends DBTypeList // Sockets w/ Gems if (!empty($enhance['g'])) { - $gems = DB::Aowow()->select( + $gems = DB::Aowow()->selectAssoc( 'SELECT it.`id` AS ARRAY_KEY, ic.`name` AS "iconString", ae.*, it.`gemColorMask` AS "colorMask" - FROM ?_items it - JOIN ?_itemenchantment ae ON ae.`id` = it.`gemEnchantmentId` - JOIN ?_icons ic ON ic.`id` = it.`iconId` - WHERE it.`id` IN (?a)', + FROM ::items it + JOIN ::itemenchantment ae ON ae.`id` = it.`gemEnchantmentId` + JOIN ::icons ic ON ic.`id` = it.`iconId` + WHERE it.`id` IN %in', $enhance['g'] ); @@ -849,7 +848,7 @@ class ItemList extends DBTypeList if ($_ = $this->curTpl['socketBonus']) { - $sbonus = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE `id` = ?d', $_); + $sbonus = DB::Aowow()->selectRow('SELECT * FROM ::itemenchantment WHERE `id` = %i', $_); $x .= '<span class="q'.($hasMatch ? '2' : '0').'">'.Lang::item('socketBonus', ['<a href="?enchantment='.$_.'">'.Util::localizedString($sbonus, 'name').'</a>']).'</span><br />'; } @@ -1033,10 +1032,10 @@ class ItemList extends DBTypeList } } - $pieces = DB::Aowow()->select( + $pieces = DB::Aowow()->selectAssoc( 'SELECT b.`id` AS ARRAY_KEY, b.`name_loc0`, b.`name_loc2`, b.`name_loc3`, b.`name_loc4`, b.`name_loc6`, b.`name_loc8`, GROUP_CONCAT(a.`id` SEPARATOR ":") AS "equiv" - FROM ?_items a, ?_items b - WHERE a.`slotBak` = b.`slotBak` AND a.`itemset` = b.`itemset` AND b.`id` IN (?a) + FROM ::items a, ::items b + WHERE a.`slotBak` = b.`slotBak` AND a.`itemset` = b.`itemset` AND b.`id` IN %in GROUP BY b.`id`', array_keys($itemset->pieceToSet) ); @@ -1212,8 +1211,8 @@ class ItemList extends DBTypeList { // is it available for this item? .. does it even exist?! if (empty($this->enhanceR)) - if (DB::World()->selectCell('SELECT 1 FROM item_enchantment_template WHERE `entry` = ?d AND `ench` = ?d', abs($this->getField('randomEnchant')), abs($randId))) - if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_itemrandomenchant WHERE `id` = ?d', $randId)) + if (DB::World()->selectCell('SELECT 1 FROM item_enchantment_template WHERE `entry` = %i AND `ench` = %i', abs($this->getField('randomEnchant')), abs($randId))) + if ($_ = DB::Aowow()->selectRow('SELECT * FROM ::itemrandomenchant WHERE `id` = %i', $randId)) $this->enhanceR = $_; return !empty($this->enhanceR); @@ -1223,7 +1222,7 @@ class ItemList extends DBTypeList public function generateEnchSuffixFactor() : float { if (empty($this->randPropPoints[$this->curTpl['itemLevel']])) - $this->randPropPoints[$this->curTpl['itemLevel']] = DB::Aowow()->selectRow('SELECT * FROM ?_itemrandomproppoints WHERE `id` = ?', $this->curTpl['itemLevel']); + $this->randPropPoints[$this->curTpl['itemLevel']] = DB::Aowow()->selectRow('SELECT * FROM ::itemrandomproppoints WHERE `id` = %s', $this->curTpl['itemLevel']); $rpp = &$this->randPropPoints[$this->curTpl['itemLevel']]; @@ -1288,8 +1287,7 @@ class ItemList extends DBTypeList if ($enchantments) { - $eStats = DB::Aowow()->select('SELECT *, `typeId` AS ARRAY_KEY FROM ?_item_stats WHERE `type` = ?d AND `typeId` IN (?a)', Type::ENCHANTMENT, array_keys($enchantments)); - Util::checkNumeric($eStats); + $eStats = DB::Aowow()->selectAssoc('SELECT *, `typeId` AS ARRAY_KEY FROM ::item_stats WHERE `type` = %i AND `typeId` IN %in', Type::ENCHANTMENT, array_keys($enchantments)); // and merge enchantments back foreach ($enchantments as $eId => $items) @@ -1333,8 +1331,8 @@ class ItemList extends DBTypeList 'SELECT `effect1Id`, `effect1TriggerSpell`, `effect1AuraId`, `effect1MiscValue`, `effect1BasePoints`, `effect1DieSides`, `effect2Id`, `effect2TriggerSpell`, `effect2AuraId`, `effect2MiscValue`, `effect2BasePoints`, `effect2DieSides`, `effect3Id`, `effect3TriggerSpell`, `effect3AuraId`, `effect3MiscValue`, `effect3BasePoints`, `effect3DieSides` - FROM ?_spell - WHERE `id` = ?d', + FROM ::spell + WHERE `id` = %i', $this->curTpl['spellId'.$h] )) $onUseStats->fromSpell($spell); @@ -1393,7 +1391,7 @@ class ItemList extends DBTypeList return 0.0; $subClasses = [ITEM_SUBCLASS_MISC_WEAPON]; - $weaponTypeMask = DB::Aowow()->selectCell('SELECT `weaponTypeMask` FROM ?_classes WHERE `id` = ?d', ChrClass::DRUID->value); + $weaponTypeMask = DB::Aowow()->selectCell('SELECT `weaponTypeMask` FROM ::classes WHERE `id` = %i', ChrClass::DRUID->value); if ($weaponTypeMask) for ($i = 0; $i < 21; $i++) if ($weaponTypeMask & (1 << $i)) @@ -1483,12 +1481,12 @@ class ItemList extends DBTypeList if ($mask & (1 << $i)) $field = Util::$ssdMaskFields[$i]; - return $field ? DB::Aowow()->selectCell('SELECT ?# FROM ?_scalingstatvalues WHERE `id` = ?d', $field, $this->ssd[$this->id]['maxLevel']) : 0; + return $field ? DB::Aowow()->selectCell('SELECT %n FROM ::scalingstatvalues WHERE `id` = %i', $field, $this->ssd[$this->id]['maxLevel']) : 0; } private function initScalingStats() : void { - $this->ssd[$this->id] = DB::Aowow()->selectRow('SELECT * FROM ?_scalingstatdistribution WHERE `id` = ?d', $this->curTpl['scalingStatDistribution']); + $this->ssd[$this->id] = DB::Aowow()->selectRow('SELECT * FROM ::scalingstatdistribution WHERE `id` = %i', $this->curTpl['scalingStatDistribution']); if (!$this->ssd[$this->id]) return; @@ -1545,9 +1543,9 @@ class ItemList extends DBTypeList return; // remember: id < 0: randomSuffix; id > 0: randomProperty - $subItemTpls = DB::World()->select( - 'SELECT CAST( `entry` AS SIGNED) AS ARRAY_KEY, CAST( `ench` AS SIGNED) AS ARRAY_KEY2, `chance` FROM item_enchantment_template WHERE `entry` IN (?a) UNION - SELECT CAST(-`entry` AS SIGNED) AS ARRAY_KEY, CAST(-`ench` AS SIGNED) AS ARRAY_KEY2, `chance` FROM item_enchantment_template WHERE `entry` IN (?a)', + $subItemTpls = DB::World()->selectAssoc( + 'SELECT CAST( `entry` AS SIGNED) AS ARRAY_KEY, CAST( `ench` AS SIGNED) AS ARRAY_KEY2, `chance` FROM item_enchantment_template WHERE `entry` IN %in UNION + SELECT CAST(-`entry` AS SIGNED) AS ARRAY_KEY, CAST(-`ench` AS SIGNED) AS ARRAY_KEY2, `chance` FROM item_enchantment_template WHERE `entry` IN %in', array_keys(array_filter($subItemIds, fn($v) => $v > 0)) ?: [0], array_keys(array_filter($subItemIds, fn($v) => $v < 0)) ?: [0] ); @@ -1559,7 +1557,7 @@ class ItemList extends DBTypeList if (!$randIds) return; - $randEnchants = DB::Aowow()->select('SELECT *, `id` AS ARRAY_KEY FROM ?_itemrandomenchant WHERE `id` IN (?a)', $randIds); + $randEnchants = DB::Aowow()->selectAssoc('SELECT *, `id` AS ARRAY_KEY FROM ::itemrandomenchant WHERE `id` IN %in', $randIds); $enchIds = array_unique(array_merge( array_column($randEnchants, 'enchantId1'), array_column($randEnchants, 'enchantId2'), @@ -1750,8 +1748,8 @@ class ItemListFilter extends Filter public const /* int */ GROUP_BY_SOURCE = 3; private array $ubFilter = []; // usable-by - limit weapon/armor selection per CharClass - itemClass => available itemsubclasses - private string $extCostQuery = 'SELECT `item` FROM npc_vendor WHERE `extendedCost` IN (?a) UNION - SELECT `item` FROM game_event_npc_vendor WHERE `extendedCost` IN (?a)'; + private string $extCostQuery = 'SELECT `item` FROM npc_vendor WHERE `extendedCost` IN %in UNION + SELECT `item` FROM game_event_npc_vendor WHERE `extendedCost` IN %in'; protected string $type = 'items'; protected static array $enums = array( @@ -2029,7 +2027,7 @@ class ItemListFilter extends Filter } if (count($this->wtCnd) > 1) - array_unshift($this->wtCnd, 'OR'); + array_unshift($this->wtCnd, DB::OR); else if (count($this->wtCnd) == 1) $this->wtCnd = $this->wtCnd[0]; @@ -2049,7 +2047,7 @@ class ItemListFilter extends Filter { if (!$this->ubFilter) { - $classes = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `weaponTypeMask` AS "0", `armorTypeMask` AS "1" FROM ?_classes'); + $classes = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `weaponTypeMask` AS "0", `armorTypeMask` AS "1" FROM ::classes'); foreach ($classes as $cId => [$weaponTypeMask, $armorTypeMask]) { // preselect misc subclasses @@ -2073,7 +2071,7 @@ class ItemListFilter extends Filter $parts = []; $_v = $this->values; - // weights + // weights [list] if ($_v['wt'] && $_v['wtv']) { // gm - gem quality (qualityId) @@ -2086,10 +2084,10 @@ class ItemListFilter extends Filter $this->fiExtraCols[] = $_; } - // upgrade for [form only] + // upgrade for [list] if ($_v['upg']) { - if ($this->upgrades = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `slot` FROM ?_items WHERE `class` IN (?a) AND `id` IN (?a)', [ITEM_CLASS_WEAPON, ITEM_CLASS_GEM, ITEM_CLASS_ARMOR], $_v['upg'])) + if ($this->upgrades = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `slot` FROM ::items WHERE `class` IN %in AND `id` IN %in', [ITEM_CLASS_WEAPON, ITEM_CLASS_GEM, ITEM_CLASS_ARMOR], $_v['upg'])) $parts[] = ['slot', $this->upgrades]; else $_v['upg'] = null; @@ -2100,17 +2098,17 @@ class ItemListFilter extends Filter if ($_ = $this->buildMatchLookup(['na' => 'name_loc'.Lang::getLocale()->value])) $parts[] = $_; - // usable-by (not excluded by requiredClass && armor or weapons match mask from ?_classes) + // usable-by (not excluded by requiredClass && armor or weapons match mask from ::classes) if ($_v['ub']) { $parts[] = array( - 'AND', - ['OR', ['requiredClass', 0], ['requiredClass', $this->list2Mask((array)$_v['ub']), '&']], + DB::AND, + [DB::OR, ['requiredClass', 0], ['requiredClass', $this->list2Mask((array)$_v['ub']), '&']], [ - 'OR', + DB::OR, ['class', [ITEM_CLASS_WEAPON, ITEM_CLASS_ARMOR], '!'], - ['AND', ['class', ITEM_CLASS_WEAPON], ['subclassbak', $this->ubFilter[$_v['ub']][ITEM_CLASS_WEAPON]]], - ['AND', ['class', ITEM_CLASS_ARMOR], ['subclassbak', $this->ubFilter[$_v['ub']][ITEM_CLASS_ARMOR]]] + [DB::AND, ['class', ITEM_CLASS_WEAPON], ['subclassbak', $this->ubFilter[$_v['ub']][ITEM_CLASS_WEAPON]]], + [DB::AND, ['class', ITEM_CLASS_ARMOR], ['subclassbak', $this->ubFilter[$_v['ub']][ITEM_CLASS_ARMOR]]] ] ); } @@ -2132,12 +2130,11 @@ class ItemListFilter extends Filter { $parts[] = match ($_v['si']) { - // in theory an item could be requiring orc|nightelf etc. and would then be SIDE_BOTH without cleanly fitting the filters below, but in that case; WTF are you doing?! - SIDE_BOTH => ['AND', [['flagsExtra', 0x3, '&'], [0, 3]], ['requiredRace', 0]], - -SIDE_HORDE => ['OR', [['flagsExtra', 0x3, '&'], 1], ['requiredRace', ChrRace::MASK_HORDE, '&']], - -SIDE_ALLIANCE => ['OR', [['flagsExtra', 0x3, '&'], 2], ['requiredRace', ChrRace::MASK_ALLIANCE, '&']], - SIDE_HORDE => ['AND', [['flagsExtra', 0x3, '&'], [0, 1]], ['OR', ['requiredRace', 0], ['requiredRace', ChrRace::MASK_HORDE, '&']]], - SIDE_ALLIANCE => ['AND', [['flagsExtra', 0x3, '&'], [0, 2]], ['OR', ['requiredRace', 0], ['requiredRace', ChrRace::MASK_ALLIANCE, '&']]], + SIDE_BOTH => [DB::OR, [['flagsExtra', 0x3, '&'], [0, 3]], ['requiredRace', 0]], + -SIDE_HORDE => [DB::OR, [['flagsExtra', 0x3, '&'], 1], ['requiredRace', ChrRace::MASK_HORDE, '&']], + -SIDE_ALLIANCE => [DB::OR, [['flagsExtra', 0x3, '&'], 2], ['requiredRace', ChrRace::MASK_ALLIANCE, '&']], + SIDE_HORDE => [DB::AND, [['flagsExtra', 0x3, '&'], [0, 1]], [DB::OR, ['requiredRace', 0], ['requiredRace', ChrRace::MASK_HORDE, '&']]], + SIDE_ALLIANCE => [DB::AND, [['flagsExtra', 0x3, '&'], [0, 2]], [DB::OR, ['requiredRace', 0], ['requiredRace', ChrRace::MASK_ALLIANCE, '&']]], }; } @@ -2186,7 +2183,7 @@ class ItemListFilter extends Filter return match ($crs) { // Meta, Red, Yellow, Blue - 1, 2, 3, 4 => ['OR', ['socketColor1', 1 << ($crs - 1)], ['socketColor2', 1 << ($crs - 1)], ['socketColor3', 1 << ($crs - 1)]], + 1, 2, 3, 4 => [DB::OR, ['socketColor1', 1 << ($crs - 1)], ['socketColor2', 1 << ($crs - 1)], ['socketColor3', 1 << ($crs - 1)]], 5 => ['is.nsockets', 0, '!'], // Yes 6 => ['is.nsockets', 0], // No default => null @@ -2198,7 +2195,7 @@ class ItemListFilter extends Filter return match ($crs) { // Meta, Red, Yellow, Blue - 1, 2, 3, 4 => ['AND', ['gemEnchantmentId', 0, '!'], ['gemColorMask', 1 << ($crs - 1), '&']], + 1, 2, 3, 4 => [DB::AND, ['gemEnchantmentId', 0, '!'], ['gemColorMask', 1 << ($crs - 1), '&']], 5 => ['gemEnchantmentId', 0, '!'], // Yes 6 => ['gemEnchantmentId', 0], // No default => null @@ -2210,7 +2207,7 @@ class ItemListFilter extends Filter return match ($crs) { // major, minor - 1, 2 => ['AND', ['class', ITEM_CLASS_GLYPH], ['subSubClass', $crs]], + 1, 2 => [DB::AND, ['class', ITEM_CLASS_GLYPH], ['subSubClass', $crs]], default => null }; } @@ -2221,14 +2218,14 @@ class ItemListFilter extends Filter if (!$this->tokenizeString($cr, $n)) return null; - $parts = []; + $where = []; foreach ($this->inTokens[$cr] ?? [] as $tok) - $parts[] = sprintf('name_loc%d LIKE "%%%s%%"', Lang::getLocale()->value, mysqli_real_escape_string(DB::Aowow()->link, $tok)); + $where[] = ['name_loc%i LIKE %~like~', Lang::getLocale()->value, $tok]; foreach ($this->exTokens[$cr] ?? [] as $tok) - $parts[] = sprintf('name_loc%d NOT LIKE "%%%s%%"', Lang::getLocale()->value, mysqli_real_escape_string(DB::Aowow()->link, $tok)); + $where[] = ['name_loc%i NOT LIKE %~like~', Lang::getLocale()->value, $tok]; - $randIds = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, ABS(`id`) AS `id`, name_loc?d, `name_loc0` FROM ?_itemrandomenchant WHERE '.implode(' AND ', $parts), Lang::getLocale()->value); - $tplIds = $randIds ? DB::World()->select('SELECT `entry`, `ench` FROM item_enchantment_template WHERE `ench` IN (?a)', array_column($randIds, 'id')) : []; + $randIds = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, ABS(`id`) AS `id`, name_loc%i, `name_loc0` FROM ::itemrandomenchant WHERE %and', Lang::getLocale()->value, $where); + $tplIds = $randIds ? DB::World()->selectAssoc('SELECT `entry`, `ench` FROM item_enchantment_template WHERE `ench` IN %in', array_column($randIds, 'id')) : []; foreach ($tplIds as &$set) { $z = array_column($randIds, 'id'); @@ -2260,7 +2257,7 @@ class ItemListFilter extends Filter $this->fiExtraCols[] = $cr; $items = [0]; - if ($costs = DB::Aowow()->selectCol('SELECT `id` FROM ?_itemextendedcost WHERE `reqPersonalrating` '.$crs.' '.$crv)) + if ($costs = DB::Aowow()->selectCol('SELECT `id` FROM ::itemextendedcost WHERE `reqPersonalrating` %SQL %i', $crs, $crv)) $items = DB::World()->selectCol($this->extCostQuery, $costs, $costs); return ['id', $items]; @@ -2285,7 +2282,7 @@ class ItemListFilter extends Filter if (!$this->checkInput(parent::V_RANGE, [SPELL_SCHOOL_NORMAL, SPELL_SCHOOL_ARCANE], $crs)) return null; - return ['OR', ['dmgType1', $crs], ['dmgType2', $crs]]; + return [DB::OR, ['dmgType1', $crs], ['dmgType2', $crs]]; } protected function cbArmorBonus(int $cr, int $crs, string $crv) : ?array @@ -2294,7 +2291,7 @@ class ItemListFilter extends Filter return null; $this->fiExtraCols[] = $cr; - return ['AND', ['armordamagemodifier', $crv, $crs], ['class', ITEM_CLASS_ARMOR]]; + return [DB::AND, ['armordamagemodifier', $crv, $crs], ['class', ITEM_CLASS_ARMOR]]; } protected function cbCraftedByProf(int $cr, int $crs, string $crv) : ?array @@ -2314,7 +2311,7 @@ class ItemListFilter extends Filter protected function cbQuestRewardIn(int $cr, int $crs, string $crv) : ?array { if (in_array($crs, self::$enums[$cr])) - return ['AND', ['src.src4', null, '!'], ['src.moreZoneId', $crs]]; + return [DB::AND, ['src.src4', null, '!'], ['src.moreZoneId', $crs]]; else if ($crs == parent::ENUM_ANY) return ['src.src4', null, '!']; // well, this seems a bit redundant.. @@ -2324,7 +2321,7 @@ class ItemListFilter extends Filter protected function cbDropsInZone(int $cr, int $crs, string $crv) : ?array { if (in_array($crs, self::$enums[$cr])) - return ['AND', ['src.src2', null, '!'], ['src.moreZoneId', $crs]]; + return [DB::AND, ['src.src2', null, '!'], ['src.moreZoneId', $crs]]; else if ($crs == parent::ENUM_ANY) return ['src.src2', null, '!']; // well, this seems a bit redundant.. @@ -2334,9 +2331,9 @@ class ItemListFilter extends Filter protected function cbDropsInInstance(int $cr, int $crs, string $crv, int $moreFlag, int $modeBit) : ?array { if (in_array($crs, self::$enums[$cr])) - return ['AND', ['src.src2', $modeBit, '&'], ['src.moreMask', $moreFlag, '&'], ['src.moreZoneId', $crs]]; + return [DB::AND, ['src.src2', $modeBit, '&'], ['src.moreMask', $moreFlag, '&'], ['src.moreZoneId', $crs]]; else if ($crs == parent::ENUM_ANY) - return ['AND', ['src.src2', $modeBit, '&'], ['src.moreMask', $moreFlag, '&']]; + return [DB::AND, ['src.src2', $modeBit, '&'], ['src.moreMask', $moreFlag, '&']]; return null; } @@ -2351,7 +2348,7 @@ class ItemListFilter extends Filter return null; $costs = DB::Aowow()->selectCol( - 'SELECT `id` FROM ?_itemextendedcost WHERE `reqItemId1` IN (?a) OR `reqItemId2` IN (?a) OR `reqItemId3` IN (?a) OR `reqItemId4` IN (?a) OR `reqItemId5` IN (?a)', + 'SELECT `id` FROM ::itemextendedcost WHERE `reqItemId1` IN %in OR `reqItemId2` IN %in OR `reqItemId3` IN %in OR `reqItemId4` IN %in OR `reqItemId5` IN %in', $_, $_, $_, $_, $_ ); if ($items = DB::World()->selectCol($this->extCostQuery, $costs, $costs)) @@ -2365,7 +2362,7 @@ class ItemListFilter extends Filter if (!Util::checkNumeric($crv, NUM_CAST_INT)) return null; - if ($iIds = DB::World()->selectCol('SELECT `item` FROM npc_vendor WHERE `entry` = ?d UNION SELECT `item` FROM game_event_npc_vendor v JOIN creature c ON c.`guid` = v.`guid` WHERE c.`id` = ?d', $crv, $crv)) + if ($iIds = DB::World()->selectCol('SELECT `item` FROM npc_vendor WHERE `entry` = %i UNION SELECT `item` FROM game_event_npc_vendor v JOIN creature c ON c.`guid` = v.`guid` WHERE c.`id` = %i', $crv, $crv)) return ['i.id', $iIds]; else return [0]; @@ -2380,7 +2377,7 @@ class ItemListFilter extends Filter { // todo: do something sensible.. // // todo (med): get the avgbuyout into the listview - // if ($_ = DB::Characters()->select('SELECT ii.itemEntry AS ARRAY_KEY, AVG(ah.buyoutprice / ii.count) AS buyout FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = ii.guid GROUP BY ii.itemEntry HAVING buyout '.$crs.' ?f', $c[1])) + // if ($_ = DB::Characters()->selectAssoc('SELECT ii.itemEntry AS ARRAY_KEY, AVG(ah.buyoutprice / ii.count) AS buyout FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = ii.guid GROUP BY ii.itemEntry HAVING buyout '.$crs.' %f', $c[1])) // return ['i.id', array_keys($_)]; // else // return [0]; @@ -2396,7 +2393,7 @@ class ItemListFilter extends Filter return null; $this->fiExtraCols[] = $cr; - return ['AND', ['flags', ITEM_FLAG_OPENABLE, '&'], ['((minMoneyLoot + maxMoneyLoot) / 2)', $crv, $crs]]; + return [DB::AND, ['flags', ITEM_FLAG_OPENABLE, '&'], ['((minMoneyLoot + maxMoneyLoot) / 2)', $crv, $crs]]; } protected function cbCooldown(int $cr, int $crs, string $crv) : ?array @@ -2410,12 +2407,12 @@ class ItemListFilter extends Filter $this->extraOpts['is']['s'][] = ', GREATEST(`spellCooldown1`, `spellCooldown2`, `spellCooldown3`, `spellCooldown4`, `spellCooldown5`) AS "cooldown"'; return [ - 'OR', - ['AND', ['spellTrigger1', SPELL_TRIGGER_USE], ['spellId1', 0, '!'], ['spellCooldown1', 0, '>'], ['spellCooldown1', $crv, $crs]], - ['AND', ['spellTrigger2', SPELL_TRIGGER_USE], ['spellId2', 0, '!'], ['spellCooldown2', 0, '>'], ['spellCooldown2', $crv, $crs]], - ['AND', ['spellTrigger3', SPELL_TRIGGER_USE], ['spellId3', 0, '!'], ['spellCooldown3', 0, '>'], ['spellCooldown3', $crv, $crs]], - ['AND', ['spellTrigger4', SPELL_TRIGGER_USE], ['spellId4', 0, '!'], ['spellCooldown4', 0, '>'], ['spellCooldown4', $crv, $crs]], - ['AND', ['spellTrigger5', SPELL_TRIGGER_USE], ['spellId5', 0, '!'], ['spellCooldown5', 0, '>'], ['spellCooldown5', $crv, $crs]], + DB::OR, + [DB::AND, ['spellTrigger1', SPELL_TRIGGER_USE], ['spellId1', 0, '!'], ['spellCooldown1', 0, '>'], ['spellCooldown1', $crv, $crs]], + [DB::AND, ['spellTrigger2', SPELL_TRIGGER_USE], ['spellId2', 0, '!'], ['spellCooldown2', 0, '>'], ['spellCooldown2', $crv, $crs]], + [DB::AND, ['spellTrigger3', SPELL_TRIGGER_USE], ['spellId3', 0, '!'], ['spellCooldown3', 0, '>'], ['spellCooldown3', $crv, $crs]], + [DB::AND, ['spellTrigger4', SPELL_TRIGGER_USE], ['spellId4', 0, '!'], ['spellCooldown4', 0, '>'], ['spellCooldown4', $crv, $crs]], + [DB::AND, ['spellTrigger5', SPELL_TRIGGER_USE], ['spellId5', 0, '!'], ['spellCooldown5', 0, '>'], ['spellCooldown5', $crv, $crs]], ]; } @@ -2426,11 +2423,11 @@ class ItemListFilter extends Filter // any 1 => ['startQuest', 0, '>'], // exclude horde only - 2 => ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], SIDE_HORDE]], + 2 => [DB::AND, ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], SIDE_HORDE]], // exclude alliance only - 3 => ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], SIDE_ALLIANCE]], + 3 => [DB::AND, ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], SIDE_ALLIANCE]], // both - 4 => ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], 0]], + 4 => [DB::AND, ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], 0]], // none 5 => ['startQuest', 0], default => null @@ -2458,7 +2455,7 @@ class ItemListFilter extends Filter if (!$this->int2Bool($crs)) return null; - $costs = DB::Aowow()->selectCol('SELECT `id` FROM ?_itemextendedcost WHERE ?# > 0', $field); + $costs = DB::Aowow()->selectCol('SELECT `id` FROM ::itemextendedcost WHERE %n > 0', $field); if ($items = DB::World()->selectCol($this->extCostQuery, $costs, $costs)) return ['id', $items, $crs ? null : '!']; @@ -2474,35 +2471,42 @@ class ItemListFilter extends Filter return null; $refResults = []; - $newRefs = DB::World()->selectCol('SELECT `entry` FROM ?# WHERE `item` = ?d AND `reference` = 0', Loot::REFERENCE, $crs); + $newRefs = DB::World()->selectCol('SELECT `entry` FROM %n WHERE `item` = %i AND `reference` = 0', Loot::REFERENCE, $crs); while ($newRefs) { $refResults += $newRefs; - $newRefs = DB::World()->selectCol('SELECT `entry` FROM ?# WHERE `reference` IN (?a)', Loot::REFERENCE, $newRefs); + $newRefs = DB::World()->selectCol('SELECT `entry` FROM %n WHERE `reference` IN %in', Loot::REFERENCE, $newRefs); } - $lootIds = DB::World()->selectCol('SELECT `entry` FROM ?# WHERE {`reference` IN (?a) OR }(`reference` = 0 AND `item` = ?d)', Loot::DISENCHANT, $refResults ?: DBSIMPLE_SKIP, $crs); + $lootIds = DB::World()->selectCol('SELECT `entry` FROM %n', Loot::DISENCHANT, 'WHERE %if', $refResults, '`reference` IN %in OR', $refResults, '%end (`reference` = 0 AND `item` = %i)', $crs); return $lootIds ? ['disenchantId', $lootIds] : [0]; } protected function cbObjectiveOfQuest(int $cr, int $crs, string $crv) : ?array { - $w = match ($crs) + $where = match ($crs) { - 1, 5 => 1, // Yes / No - 2 => '`reqRaceMask` & '.ChrRace::MASK_ALLIANCE.' AND (`reqRaceMask` & '.ChrRace::MASK_HORDE.') = 0', // Alliance - 3 => '`reqRaceMask` & '.ChrRace::MASK_HORDE.' AND (`reqRaceMask` & '.ChrRace::MASK_ALLIANCE.') = 0', // Horde - 4 => '(`reqRaceMask` & '.ChrRace::MASK_ALLIANCE.' AND `reqRaceMask` & '.ChrRace::MASK_HORDE.') OR `reqRaceMask` = 0', // Both + // Yes / No + 1, 5 => [1], + // Alliance + 2 => [['`reqRaceMask` & %i', ChrRace::MASK_ALLIANCE], ['(`reqRaceMask` & %i) = 0', ChrRace::MASK_HORDE]], + // Horde + 3 => [['`reqRaceMask` & %i', ChrRace::MASK_HORDE], ['(`reqRaceMask` & %i) = 0', ChrRace::MASK_ALLIANCE]], + // Both + 4 => [[DB::OR, [['`reqRaceMask` = 0'], [DB::AND, [['`reqRaceMask` & %i', ChrRace::MASK_ALLIANCE], ['`reqRaceMask` & %i', ChrRace::MASK_HORDE]]]]]], default => null }; - $itemIds = DB::Aowow()->selectCol(sprintf( - 'SELECT `reqItemId1` FROM ?_quests WHERE %1$s UNION SELECT `reqItemId2` FROM ?_quests WHERE %1$s UNION - SELECT `reqItemId3` FROM ?_quests WHERE %1$s UNION SELECT `reqItemId4` FROM ?_quests WHERE %1$s UNION - SELECT `reqItemId5` FROM ?_quests WHERE %1$s UNION SELECT `reqItemId6` FROM ?_quests WHERE %1$s', - $w - )); + if (!$where) + return [0]; + + $itemIds = DB::Aowow()->selectCol( + 'SELECT `reqItemId1` FROM ::quests WHERE %and UNION SELECT `reqItemId2` FROM ::quests WHERE %and UNION + SELECT `reqItemId3` FROM ::quests WHERE %and UNION SELECT `reqItemId4` FROM ::quests WHERE %and UNION + SELECT `reqItemId5` FROM ::quests WHERE %and UNION SELECT `reqItemId6` FROM ::quests WHERE %and', + $where, $where, $where, $where, $where, $where + ); if ($itemIds) return ['id', $itemIds, $crs == 5 ? '!' : null]; @@ -2520,11 +2524,11 @@ class ItemListFilter extends Filter return null; $ids = []; - $spells = DB::Aowow()->select( // todo (med): hmm, selecting all using SpellList would exhaust 128MB of memory :x .. see, that we only select the fields that are really needed + $spells = DB::Aowow()->selectAssoc( // todo (med): hmm, selecting all using SpellList would exhaust 128MB of memory :x .. see, that we only select the fields that are really needed 'SELECT `reagent1`, `reagent2`, `reagent3`, `reagent4`, `reagent5`, `reagent6`, `reagent7`, `reagent8`, `reagentCount1`, `reagentCount2`, `reagentCount3`, `reagentCount4`, `reagentCount5`, `reagentCount6`, `reagentCount7`, `reagentCount8` - FROM ?_spell - WHERE `skillLine1` IN (?a)', + FROM ::spell + WHERE `skillLine1` IN %in', is_bool($_) ? array_filter(self::$enums[99], "is_numeric") : $_ ); foreach ($spells as $spell) @@ -2550,7 +2554,7 @@ class ItemListFilter extends Filter return ['src.src'.$_, null, '!']; else if ($_) // any { - $foo = ['OR']; + $foo = [DB::OR]; foreach (self::$enums[$cr] as $bar) if (is_int($bar)) $foo[] = ['src.src'.$bar, null, '!']; diff --git a/includes/dbtypes/itemset.class.php b/includes/dbtypes/itemset.class.php index 618f2128..064ac4a7 100644 --- a/includes/dbtypes/itemset.class.php +++ b/includes/dbtypes/itemset.class.php @@ -12,16 +12,16 @@ class ItemsetList extends DBTypeList public static int $type = Type::ITEMSET; public static string $brickFile = 'itemset'; - public static string $dataTable = '?_itemset'; + public static string $dataTable = '::itemset'; public array $pieceToSet = []; // used to build g_items and search private array $classes = []; // used to build g_classes - protected string $queryBase = 'SELECT `set`.*, `set`.`id` AS ARRAY_KEY FROM ?_itemset `set`'; + protected string $queryBase = 'SELECT `set`.*, `set`.`id` AS ARRAY_KEY FROM ::itemset `set`'; protected array $queryOpts = array( 'set' => ['o' => 'maxlevel DESC'], - 'e' => ['j' => ['?_events e ON `e`.`id` = `set`.`eventId`', true], 's' => ', e.`holidayId`'], - 'src' => ['j' => ['?_source src ON `src`.`typeId` = `set`.`id` AND `src`.`type` = 4', true], 's' => ', `src1`, `src2`, `src3`, `src4`, `src5`, `src6`, `src7`, `src8`, `src9`, `src10`, `src11`, `src12`, `src13`, `src14`, `src15`, `src16`, `src17`, `src18`, `src19`, `src20`, `src21`, `src22`, `src23`, `src24`'] + 'e' => ['j' => ['::events e ON `e`.`id` = `set`.`eventId`', true], 's' => ', e.`holidayId`'], + 'src' => ['j' => ['::source src ON `src`.`typeId` = `set`.`id` AND `src`.`type` = 4', true], 's' => ', `src1`, `src2`, `src3`, `src4`, `src5`, `src6`, `src7`, `src8`, `src9`, `src10`, `src11`, `src12`, `src13`, `src14`, `src15`, `src16`, `src17`, `src18`, `src19`, `src20`, `src21`, `src22`, `src23`, `src24`'] ); public function __construct(array $conditions = [], array $miscData = []) diff --git a/includes/dbtypes/mail.class.php b/includes/dbtypes/mail.class.php index 9ef67241..0e142428 100644 --- a/includes/dbtypes/mail.class.php +++ b/includes/dbtypes/mail.class.php @@ -10,9 +10,9 @@ class MailList extends DBTypeList { public static int $type = Type::MAIL; public static string $brickFile = 'mail'; - public static string $dataTable = '?_mails'; + public static string $dataTable = '::mails'; - protected string $queryBase = 'SELECT m.*, m.`id` AS ARRAY_KEY FROM ?_mails m'; + protected string $queryBase = 'SELECT m.*, m.`id` AS ARRAY_KEY FROM ::mails m'; protected array $queryOpts = []; public function __construct(array $conditions = [], array $miscData = []) @@ -36,7 +36,7 @@ class MailList extends DBTypeList public static function getName(int $id) : ?LocString { - if ($n = DB::Aowow()->SelectRow('SELECT `subject_loc0`, `subject_loc2`, `subject_loc3`, `subject_loc4`, `subject_loc6`, `subject_loc8` FROM ?# WHERE `id` = ?d', self::$dataTable, $id)) + if ($n = DB::Aowow()->SelectRow('SELECT `subject_loc0`, `subject_loc2`, `subject_loc3`, `subject_loc4`, `subject_loc6`, `subject_loc8` FROM %n WHERE `id` = %i', self::$dataTable, $id)) return new LocString($n, 'subject'); return null; } diff --git a/includes/dbtypes/pet.class.php b/includes/dbtypes/pet.class.php index b0c23dea..86834fa5 100644 --- a/includes/dbtypes/pet.class.php +++ b/includes/dbtypes/pet.class.php @@ -12,12 +12,12 @@ class PetList extends DBTypeList public static int $type = Type::PET; public static string $brickFile = 'pet'; - public static string $dataTable = '?_pet'; + public static string $dataTable = '::pet'; - protected string $queryBase = 'SELECT p.*, p.`id` AS ARRAY_KEY FROM ?_pet p'; + protected string $queryBase = 'SELECT p.*, p.`id` AS ARRAY_KEY FROM ::pet p'; protected array $queryOpts = array( 'p' => [['ic']], - 'ic' => ['j' => ['?_icons ic ON p.`iconId` = ic.`id`', true], 's' => ', ic.`name` AS "iconString"'], + 'ic' => ['j' => ['::icons ic ON p.`iconId` = ic.`id`', true], 's' => ', ic.`name` AS "iconString"'], ); public function getListviewData() : array diff --git a/includes/dbtypes/profile.class.php b/includes/dbtypes/profile.class.php index df4da3a7..6c6cc58b 100644 --- a/includes/dbtypes/profile.class.php +++ b/includes/dbtypes/profile.class.php @@ -338,7 +338,7 @@ class ProfileListFilter extends Filter if ($this->useLocalList) { $this->extraOpts[$k] = array( - 'j' => [sprintf('?_profiler_completion_skills %1$s ON `%1$s`.`id` = p.`id` AND `%1$s`.`skillId` = %2$d AND `%1$s`.`value` %3$s %4$d', $k, $skillId, $crs, $crv), true], + 'j' => [sprintf('::profiler_completion_skills %1$s ON `%1$s`.`id` = p.`id` AND `%1$s`.`skillId` = %2$d AND `%1$s`.`value` %3$s %4$d', $k, $skillId, $crs, $crv), true], 's' => [', '.$k.'.`value` AS "'.$col.'"'] ); return [$k.'.skillId', null, '!']; @@ -365,7 +365,7 @@ class ProfileListFilter extends Filter if ($this->useLocalList) { - $this->extraOpts[$k] = ['j' => [sprintf('?_profiler_completion_achievements %1$s ON `%1$s`.`id` = p.`id` AND `%1$s`.`achievementId` = %2$d', $k, $crv), true]]; + $this->extraOpts[$k] = ['j' => [sprintf('::profiler_completion_achievements %1$s ON `%1$s`.`id` = p.`id` AND `%1$s`.`achievementId` = %2$d', $k, $crv), true]]; return [$k.'.achievementId', null, '!']; } else @@ -385,7 +385,7 @@ class ProfileListFilter extends Filter $k = 'i_'.Util::createHash(12); - $this->extraOpts[$k] = ['j' => [sprintf('?_profiler_items %1$s ON `%1$s`.`id` = p.`id` AND `%1$s`.`item` = %2$d', $k, $crv), true]]; + $this->extraOpts[$k] = ['j' => [sprintf('::profiler_items %1$s ON `%1$s`.`id` = p.`id` AND `%1$s`.`item` = %2$d', $k, $crv), true]]; return [$k.'.item', null, '!']; } @@ -416,7 +416,7 @@ class ProfileListFilter extends Filter $n = preg_replace(parent::PATTERN_NAME, '', $crv); if ($this->tokenizeString($cr, $n)) if ($_ = $this->buildLikeLookup([$cr => 'at.name'])) - return ['AND', ['at.type', $size], $_]; + return [DB::AND, ['at.type', $size], $_]; return null; } @@ -426,7 +426,7 @@ class ProfileListFilter extends Filter if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs)) return null; - return ['AND', ['at.type', $size], ['at.rating', $crv, $crs]]; + return [DB::AND, ['at.type', $size], ['at.rating', $crv, $crs]]; } protected function cbAchievs(int $cr, int $crs, string $crv) : ?array @@ -524,10 +524,10 @@ 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 `custom` = 0 AND `name` = ?', $r, $curTpl['name']) ?: 0; + $this->rnItr[$curTpl['name']] = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ::profiler_profiles WHERE `realm` = %i AND `custom` = 0 AND `name` = %s', $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)) + if ($rnItr = DB::Aowow()->selectCell('SELECT `renameItr` FROM ::profiler_profiles WHERE `realm` = %i AND `realmGUID` = %i', $r, $g)) $curTpl['renameItr'] = $rnItr; // not yet recognized: get max itr else @@ -540,9 +540,9 @@ class RemoteProfileList extends ProfileList } foreach ($talentLookup as $realm => $chars) - $talentLookup[$realm] = DB::Characters($realm)->selectCol('SELECT `guid` AS ARRAY_KEY, `spell` AS ARRAY_KEY2, `talentGroup` FROM character_talent ct WHERE `guid` IN (?a)', array_keys($chars)); + $talentLookup[$realm] = DB::Characters($realm)->selectCol('SELECT `guid` AS ARRAY_KEY, `spell` AS ARRAY_KEY2, `talentGroup` FROM character_talent ct WHERE `guid` IN %in', array_keys($chars)); - $talentSpells = DB::Aowow()->select('SELECT `spell` AS ARRAY_KEY, `tab`, `rank` FROM ?_talents WHERE `class` IN (?a)', array_unique($talentSpells)); + $talentSpells = DB::Aowow()->selectAssoc('SELECT `spell` AS ARRAY_KEY, `tab`, `rank` FROM ::talents WHERE `class` IN %in', array_unique($talentSpells)); // equalize subject distribution across realms $limit = 0; @@ -599,63 +599,75 @@ class RemoteProfileList extends ProfileList public function initializeLocalEntries() : void { + if (!$this->templates) + return; + $baseData = $guildData = []; foreach ($this->iterate() as $guid => $__) { $realmId = $this->getField('realm'); $guildGUID = $this->getField('guild'); - $baseData[$guid] = array( - 'realm' => $realmId, - 'realmGUID' => $this->getField('guid'), - 'name' => $this->getField('name'), - 'renameItr' => $this->getField('renameItr'), - 'race' => $this->getField('race'), - 'class' => $this->getField('class'), - 'level' => $this->getField('level'), - 'gender' => $this->getField('gender'), - 'guild' => $guildGUID ?: null, - 'guildrank' => $guildGUID ? $this->getField('guildrank') : null, - 'stub' => 1 - ); + $baseData['realm'][$guid] = $realmId; + $baseData['realmGUID'][$guid] = $this->getField('guid'); + $baseData['name'][$guid] = $this->getField('name'); + $baseData['renameItr'][$guid] = $this->getField('renameItr'); + $baseData['race'][$guid] = $this->getField('race'); + $baseData['class'][$guid] = $this->getField('class'); + $baseData['level'][$guid] = $this->getField('level'); + $baseData['gender'][$guid] = $this->getField('gender'); + $baseData['guild'][$guid] = $guildGUID ?: null; + $baseData['guildrank'][$guid] = $guildGUID ? $this->getField('guildrank') : null; + $baseData['stub'][$guid] = 1; - if ($guildGUID && empty($guildData[$realmId.'-'.$guildGUID])) - $guildData[$realmId.'-'.$guildGUID] = array( - 'realm' => $realmId, - 'realmGUID' => $guildGUID, - 'name' => $this->getField('guildname'), - 'nameUrl' => Profiler::urlize($this->getField('guildname')), - 'stub' => 1 - ); + if ($guildGUID) + { + $guildData['realm'][$realmId.'-'.$guildGUID] = $realmId; + $guildData['realmGUID'][$realmId.'-'.$guildGUID] = $guildGUID; + $guildData['name'][$realmId.'-'.$guildGUID] = $this->getField('guildname'); + $guildData['nameUrl'][$realmId.'-'.$guildGUID] = Profiler::urlize($this->getField('guildname')); + $guildData['stub'][$realmId.'-'.$guildGUID] = 1; + } } // basic guild data (satisfying table constraints) if ($guildData) { - foreach (Util::createSqlBatchInsert($guildData) as $ins) - DB::Aowow()->query('INSERT INTO ?_profiler_guild (?#) VALUES '.$ins.' ON DUPLICATE KEY UPDATE `id` = `id`', array_keys(reset($guildData))); + DB::Aowow()->qry('INSERT INTO ::profiler_guild %m ON DUPLICATE KEY UPDATE `id` = `id`', $guildData); // merge back local ids - $localGuilds = DB::Aowow()->selectCol('SELECT `realm` AS ARRAY_KEY, `realmGUID` AS ARRAY_KEY2, `id` FROM ?_profiler_guild WHERE `realm` IN (?a) AND `realmGUID` IN (?a)', - array_column($guildData, 'realm'), array_column($guildData, 'realmGUID') + $localGuilds = DB::Aowow()->selectCol('SELECT `realm` AS ARRAY_KEY, `realmGUID` AS ARRAY_KEY2, `id` FROM ::profiler_guild WHERE `realm` IN %in AND `realmGUID` IN %in', + $guildData['realm'], $guildData['realmGUID'] ); - foreach ($baseData as &$bd) - if ($bd['guild']) - $bd['guild'] = $localGuilds[$bd['realm']][$bd['guild']]; + foreach ($baseData['guild'] as $i => &$g) + $g = $localGuilds[$baseData['realm'][$i]][$baseData['guild'][$i]] ?? null; } // basic char data (enough for tooltips) if ($baseData) { - foreach ($baseData as $ins) - DB::Aowow()->query('INSERT INTO ?_profiler_profiles (?#) VALUES (?a) ON DUPLICATE KEY UPDATE `name` = ?, `renameItr` = ?d', array_keys($ins), array_values($ins), $ins['name'], $ins['renameItr']); + // this could have been an INSERT ON DUPLICATE KEY UPDATE if MariaDB and MySQL would behave for once! + $insertOrUpdate = $baseData; + $existing = DB::Aowow()->selectAssoc('SELECT `realm` AS ARRAY_KEY, `realmGUID` AS ARRAY_KEY2, 1 FROM ::profiler_profiles WHERE `realm` IN %in AND `realmGUID` IN %in', $insertOrUpdate['realm'], $insertOrUpdate['realmGUID']); + foreach ($insertOrUpdate['realm'] as $guid => $_) + { + if (!isset($existing[$insertOrUpdate['realm'][$guid]][$insertOrUpdate['realmGUID'][$guid]])) + continue; + + // ... ON DUPLICATE KEY UPDATE + DB::Aowow()->qry('UPDATE ::profiler_profiles SET `name` = %s, `renameItr` = %i WHERE `realm` = %i AND `realmGUID` = %i', $insertOrUpdate['name'][$guid], $insertOrUpdate['renameItr'][$guid], $insertOrUpdate['realm'][$guid], $insertOrUpdate['realmGUID'][$guid]); + foreach($insertOrUpdate as $col => $__) + unset($insertOrUpdate[$col][$guid]); + } + + // INSERT ... + if (current($insertOrUpdate)) + DB::Aowow()->qry('INSERT INTO ::profiler_profiles %m', $insertOrUpdate); // merge back local ids - $localIds = DB::Aowow()->select( - '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') + $localIds = DB::Aowow()->selectAssoc('SELECT CONCAT(`realm`, ":", `realmGUID`) AS ARRAY_KEY, `id`, `gearscore` FROM ::profiler_profiles WHERE `custom` = 0 AND `realm` IN %in AND `realmGUID` IN %in', + $baseData['realm'], $baseData['realmGUID'] ); foreach ($this->iterate() as $guid => &$_curTpl) @@ -668,13 +680,13 @@ class RemoteProfileList extends ProfileList class LocalProfileList extends ProfileList { - protected string $queryBase = 'SELECT p.*, p.`id` AS ARRAY_KEY FROM ?_profiler_profiles p'; + protected string $queryBase = 'SELECT p.*, p.`id` AS ARRAY_KEY FROM ::profiler_profiles p'; protected array $queryOpts = array( 'p' => [['g'], 'g' => 'p.`id`'], - 'ap' => ['j' => ['?_account_profiles ap ON ap.`profileId` = p.`id`', true], 's' => ', (IFNULL(ap.`extraFlags`, 0) | p.`cuFlags`) AS "cuFlags"'], - 'atm' => ['j' => ['?_profiler_arena_team_member atm ON atm.`profileId` = p.`id`', true], 's' => ', atm.`captain`, atm.`personalRating` AS "rating", atm.`seasonGames`, atm.`seasonWins`'], - 'at' => [['atm'], 'j' => ['?_profiler_arena_team at ON at.`id` = atm.`arenaTeamId`', true], 's' => ', at.`type`'], - 'g' => ['j' => ['?_profiler_guild g ON g.`id` = p.`guild`', true], 's' => ', g.`name` AS "guildname"'] + 'ap' => ['j' => ['::account_profiles ap ON ap.`profileId` = p.`id`', true], 's' => ', (IFNULL(ap.`extraFlags`, 0) | p.`cuFlags`) AS "cuFlags"'], + 'atm' => ['j' => ['::profiler_arena_team_member atm ON atm.`profileId` = p.`id`', true], 's' => ', atm.`captain`, atm.`personalRating` AS "rating", atm.`seasonGames`, atm.`seasonWins`'], + 'at' => [['atm'], 'j' => ['::profiler_arena_team at ON at.`id` = atm.`arenaTeamId`', true], 's' => ', at.`type`'], + 'g' => ['j' => ['::profiler_guild g ON g.`id` = p.`guild`', true], 's' => ', g.`name` AS "guildname"'] ); public function __construct(array $conditions = [], array $miscData = []) @@ -691,8 +703,8 @@ class LocalProfileList extends ProfileList if ($conditions && $realmIds) { - array_unshift($conditions, 'AND'); - $conditions = ['AND', ['realm', $realmIds], $conditions]; + array_unshift($conditions, DB::AND); + $conditions = [DB::AND, ['realm', $realmIds], $conditions]; } else if ($realmIds) $conditions = [['realm', $realmIds]]; diff --git a/includes/dbtypes/quest.class.php b/includes/dbtypes/quest.class.php index 7096fbba..64b74611 100644 --- a/includes/dbtypes/quest.class.php +++ b/includes/dbtypes/quest.class.php @@ -10,17 +10,17 @@ class QuestList extends DBTypeList { public static int $type = Type::QUEST; public static string $brickFile = 'quest'; - public static string $dataTable = '?_quests'; + public static string $dataTable = '::quests'; public array $requires = []; public array $rewards = []; public array $choices = []; - protected string $queryBase = 'SELECT q.*, q.`id` AS ARRAY_KEY FROM ?_quests q'; + protected string $queryBase = 'SELECT q.*, q.`id` AS ARRAY_KEY FROM ::quests q'; protected array $queryOpts = array( 'q' => [], - 'rsc' => ['j' => '?_spell rsc ON q.`rewardSpellCast` = rsc.`id`'], // limit rewardSpellCasts - 'qse' => ['j' => '?_quests_startend qse ON q.`id` = qse.`questId`', 's' => ', qse.`method`'], // groupConcat..? - 'e' => ['j' => ['?_events e ON e.`id` = q.`eventId`', true], 's' => ', e.`holidayId`'] + 'rsc' => ['j' => '::spell rsc ON q.`rewardSpellCast` = rsc.`id`'], // limit rewardSpellCasts + 'qse' => ['j' => '::quests_startend qse ON q.`id` = qse.`questId`', 's' => ', qse.`method`'], // groupConcat..? + 'e' => ['j' => ['::events e ON e.`id` = q.`eventId`', true], 's' => ', e.`holidayId`'] ); public function __construct(array $conditions = [], array $miscData = []) @@ -28,7 +28,7 @@ class QuestList extends DBTypeList parent::__construct($conditions, $miscData); // i don't like this very much - $currencies = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `itemId` FROM ?_currencies'); + $currencies = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `itemId` FROM ::currencies'); // post processing foreach ($this->iterate() as $id => &$_curTpl) @@ -171,7 +171,7 @@ class QuestList extends DBTypeList continue; [$series, $first] = DB::Aowow()->SelectRow( - 'SELECT IF(prev.`id` OR cur.`nextQuestIdChain`, 1, 0) AS "0", IF(prev.`id` IS NULL AND cur.`nextQuestIdChain`, 1, 0) AS "1" FROM ?_quests cur LEFT JOIN ?_quests prev ON prev.`nextQuestIdChain` = cur.`id` WHERE cur.`id` = ?d', + 'SELECT IF(prev.`id` OR cur.`nextQuestIdChain`, 1, 0) AS "0", IF(prev.`id` IS NULL AND cur.`nextQuestIdChain`, 1, 0) AS "1" FROM ::quests cur LEFT JOIN ::quests prev ON prev.`nextQuestIdChain` = cur.`id` WHERE cur.`id` = %i', $this->id ); @@ -539,15 +539,15 @@ class QuestListFilter extends Filter if ($_v['si']) { $excl = [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL, '!']; - $incl = ['OR', ['reqRaceMask', 0], [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL]]; + $incl = [DB::OR, ['reqRaceMask', 0], [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL]]; $parts[] = match ($_v['si']) { SIDE_BOTH => $incl, - SIDE_HORDE => ['OR', $incl, ['reqRaceMask', ChrRace::MASK_HORDE, '&']], - -SIDE_HORDE => ['AND', $excl, ['reqRaceMask', ChrRace::MASK_HORDE, '&']], - SIDE_ALLIANCE => ['OR', $incl, ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']], - -SIDE_ALLIANCE => ['AND', $excl, ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']] + SIDE_HORDE => [DB::OR, $incl, ['reqRaceMask', ChrRace::MASK_HORDE, '&']], + -SIDE_HORDE => [DB::AND, $excl, ['reqRaceMask', ChrRace::MASK_HORDE, '&']], + SIDE_ALLIANCE => [DB::OR, $incl, ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']], + -SIDE_ALLIANCE => [DB::AND, $excl, ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']] }; } @@ -566,16 +566,16 @@ class QuestListFilter extends Filter if (!in_array($crs, self::$enums[$cr])) return null; - if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_factions WHERE `id` = ?d', $crs)) + if ($_ = DB::Aowow()->selectRow('SELECT * FROM ::factions WHERE `id` = %i', $crs)) $this->fiReputationCols[] = [$crs, Util::localizedString($_, 'name')]; return [ - 'OR', - ['AND', ['rewardFactionId1', $crs], ['rewardFactionValue1', 0, $sign]], - ['AND', ['rewardFactionId2', $crs], ['rewardFactionValue2', 0, $sign]], - ['AND', ['rewardFactionId3', $crs], ['rewardFactionValue3', 0, $sign]], - ['AND', ['rewardFactionId4', $crs], ['rewardFactionValue4', 0, $sign]], - ['AND', ['rewardFactionId5', $crs], ['rewardFactionValue5', 0, $sign]] + DB::OR, + [DB::AND, ['rewardFactionId1', $crs], ['rewardFactionValue1', 0, $sign]], + [DB::AND, ['rewardFactionId2', $crs], ['rewardFactionValue2', 0, $sign]], + [DB::AND, ['rewardFactionId3', $crs], ['rewardFactionValue3', 0, $sign]], + [DB::AND, ['rewardFactionId4', $crs], ['rewardFactionValue4', 0, $sign]], + [DB::AND, ['rewardFactionId5', $crs], ['rewardFactionValue5', 0, $sign]] ]; } @@ -585,7 +585,7 @@ class QuestListFilter extends Filter { Type::NPC, Type::OBJECT, - Type::ITEM => ['AND', ['qse.type', $crs], ['qse.method', $flags, '&']], + Type::ITEM => [DB::AND, ['qse.type', $crs], ['qse.method', $flags, '&']], default => null }; } @@ -599,7 +599,7 @@ class QuestListFilter extends Filter return null; return [ - 'OR', + DB::OR, ['rewardItemId1', $crs], ['rewardItemId2', $crs], ['rewardItemId3', $crs], ['rewardItemId4', $crs], ['rewardChoiceItemId1', $crs], ['rewardChoiceItemId2', $crs], ['rewardChoiceItemId3', $crs], ['rewardChoiceItemId4', $crs], ['rewardChoiceItemId5', $crs], ['rewardChoiceItemId6', $crs] ]; @@ -642,9 +642,9 @@ class QuestListFilter extends Filter return null; if ($crs) - return ['AND', ['questSortId', 0, '>'], [['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY, '&'], 0], [['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_MONTHLY, '&'], 0]]; + return [DB::AND, ['questSortId', 0, '>'], [['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY, '&'], 0], [['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_MONTHLY, '&'], 0]]; else - return ['OR', ['questSortId', 0, '<'], ['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY, '&'], ['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_MONTHLY, '&']]; + return [DB::OR, ['questSortId', 0, '<'], ['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY, '&'], ['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_MONTHLY, '&']]; } protected function cbSpellRewards(int $cr, int $crs, string $crv) : ?array @@ -653,9 +653,9 @@ class QuestListFilter extends Filter return null; if ($crs) - return ['OR', ['sourceSpellId', 0, '>'], ['rewardSpell', 0, '>'], ['rsc.effect1Id', SpellList::EFFECTS_TEACH], ['rsc.effect2Id', SpellList::EFFECTS_TEACH], ['rsc.effect3Id', SpellList::EFFECTS_TEACH]]; + return [DB::OR, ['sourceSpellId', 0, '>'], ['rewardSpell', 0, '>'], ['rsc.effect1Id', SpellList::EFFECTS_TEACH], ['rsc.effect2Id', SpellList::EFFECTS_TEACH], ['rsc.effect3Id', SpellList::EFFECTS_TEACH]]; else - return ['AND', ['sourceSpellId', 0], ['rewardSpell', 0], ['rewardSpellCast', 0]]; + return [DB::AND, ['sourceSpellId', 0], ['rewardSpell', 0], ['rewardSpellCast', 0]]; } protected function cbEarnReputation(int $cr, int $crs, string $crv) : ?array @@ -664,11 +664,11 @@ class QuestListFilter extends Filter return null; if ($crs == parent::ENUM_ANY) - return ['OR', ['reqFactionId1', 0, '>'], ['reqFactionId2', 0, '>']]; + return [DB::OR, ['reqFactionId1', 0, '>'], ['reqFactionId2', 0, '>']]; else if ($crs == parent::ENUM_NONE) - return ['AND', ['reqFactionId1', 0], ['reqFactionId2', 0]]; + return [DB::AND, ['reqFactionId1', 0], ['reqFactionId2', 0]]; else if (in_array($crs, self::$enums[$cr])) - return ['OR', ['reqFactionId1', $crs], ['reqFactionId2', $crs]]; + return [DB::OR, ['reqFactionId1', $crs], ['reqFactionId2', $crs]]; return null; } @@ -680,11 +680,11 @@ class QuestListFilter extends Filter $_ = self::$enums[$cr][$crs]; if ($_ === true) - return ['AND', ['reqClassMask', 0, '!'], [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!']]; + return [DB::AND, ['reqClassMask', 0, '!'], [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!']]; else if ($_ === false) - return ['OR', ['reqClassMask', 0], [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL]]; + return [DB::OR, ['reqClassMask', 0], [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL]]; else if (is_int($_)) - return ['AND', ['reqClassMask', ChrClass::from($_)->toMask(), '&'], [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!']]; + return [DB::AND, ['reqClassMask', ChrClass::from($_)->toMask(), '&'], [['reqClassMask', ChrClass::MASK_ALL, '&'], ChrClass::MASK_ALL, '!']]; return null; } @@ -696,11 +696,11 @@ class QuestListFilter extends Filter $_ = self::$enums[$cr][$crs]; if ($_ === true) - return ['AND', ['reqRaceMask', 0, '!'], [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL, '!'], [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ChrRace::MASK_ALLIANCE, '!'], [['reqRaceMask', ChrRace::MASK_HORDE, '&'], ChrRace::MASK_HORDE, '!']]; + return [DB::AND, ['reqRaceMask', 0, '!'], [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL, '!'], [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ChrRace::MASK_ALLIANCE, '!'], [['reqRaceMask', ChrRace::MASK_HORDE, '&'], ChrRace::MASK_HORDE, '!']]; else if ($_ === false) - return ['OR', ['reqRaceMask', 0], ['reqRaceMask', ChrRace::MASK_ALL], ['reqRaceMask', ChrRace::MASK_ALLIANCE], ['reqRaceMask', ChrRace::MASK_HORDE]]; + return [DB::OR, ['reqRaceMask', 0], ['reqRaceMask', ChrRace::MASK_ALL], ['reqRaceMask', ChrRace::MASK_ALLIANCE], ['reqRaceMask', ChrRace::MASK_HORDE]]; else if (is_int($_)) - return ['AND', ['reqRaceMask', ChrRace::from($_)->toMask(), '&'], [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ChrRace::MASK_ALLIANCE, '!'], [['reqRaceMask', ChrRace::MASK_HORDE, '&'], ChrRace::MASK_HORDE, '!']]; + return [DB::AND, ['reqRaceMask', ChrRace::from($_)->toMask(), '&'], [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ChrRace::MASK_ALLIANCE, '!'], [['reqRaceMask', ChrRace::MASK_HORDE, '&'], ChrRace::MASK_HORDE, '!']]; return null; } @@ -710,7 +710,7 @@ class QuestListFilter extends Filter if (!$this->int2Bool($crs)) return null; - $missing = DB::Aowow()->selectCol('SELECT `questId`, BIT_OR(`method`) AS "se" FROM ?_quests_startend GROUP BY `questId` HAVING "se" <> 3'); + $missing = DB::Aowow()->selectCol('SELECT `questId`, BIT_OR(`method`) AS "se" FROM ::quests_startend GROUP BY `questId` HAVING "se" <> 3'); if ($crs) return ['id', $missing]; else diff --git a/includes/dbtypes/skill.class.php b/includes/dbtypes/skill.class.php index 2f18cd69..9aafbcb1 100644 --- a/includes/dbtypes/skill.class.php +++ b/includes/dbtypes/skill.class.php @@ -10,12 +10,12 @@ class SkillList extends DBTypeList { public static int $type = Type::SKILL; public static string $brickFile = 'skill'; - public static string $dataTable = '?_skillline'; + public static string $dataTable = '::skillline'; - protected string $queryBase = 'SELECT sl.*, sl.`id` AS ARRAY_KEY FROM ?_skillline sl'; + protected string $queryBase = 'SELECT sl.*, sl.`id` AS ARRAY_KEY FROM ::skillline sl'; protected array $queryOpts = array( 'sl' => [['ic']], - 'ic' => ['j' => ['?_icons ic ON ic.`id` = sl.`iconId`', true], 's' => ', ic.`name` AS "iconString"'], + 'ic' => ['j' => ['::icons ic ON ic.`id` = sl.`iconId`', true], 's' => ', ic.`name` AS "iconString"'], ); public function __construct(array $conditions = [], array $miscData = []) diff --git a/includes/dbtypes/sound.class.php b/includes/dbtypes/sound.class.php index 0f65f855..85f73300 100644 --- a/includes/dbtypes/sound.class.php +++ b/includes/dbtypes/sound.class.php @@ -12,10 +12,10 @@ class SoundList extends DBTypeList public static int $type = Type::SOUND; public static string $brickFile = 'sound'; - public static string $dataTable = '?_sounds'; + public static string $dataTable = '::sounds'; public static int $contribute = CONTRIBUTE_CO; - protected string $queryBase = 'SELECT s.*, s.`id` AS ARRAY_KEY FROM ?_sounds s'; + protected string $queryBase = 'SELECT s.*, s.`id` AS ARRAY_KEY FROM ::sounds s'; private array $fileBuffer = []; private static array $fileTypes = [SOUND_TYPE_OGG => MIME_TYPE_OGG, SOUND_TYPE_MP3 => MIME_TYPE_MP3]; @@ -42,7 +42,7 @@ class SoundList extends DBTypeList if ($this->fileBuffer) { - $files = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `id`, `file` AS "title", CAST(`type` AS UNSIGNED) AS "type", `path` FROM ?_sounds_files sf WHERE `id` IN (?a)', array_keys($this->fileBuffer)); + $files = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `id`, `file` AS "title", CAST(`type` AS UNSIGNED) AS "type", `path` FROM ::sounds_files sf WHERE `id` IN %in', array_keys($this->fileBuffer)); foreach ($files as $id => $data) { // 3.3.5 bandaid - need fullpath to play via wow API, remove for cata and later @@ -61,7 +61,7 @@ class SoundList extends DBTypeList public static function getName(int $id) : ?LocString { - if ($n = DB::Aowow()->SelectRow('SELECT `name` AS "name_loc0" FROM ?# WHERE `id` = ?d', self::$dataTable, $id)) + if ($n = DB::Aowow()->SelectRow('SELECT `name` AS "name_loc0" FROM %n WHERE `id` = %i', self::$dataTable, $id)) return new LocString($n); return null; } diff --git a/includes/dbtypes/spell.class.php b/includes/dbtypes/spell.class.php index bee1233c..9ce5a82b 100644 --- a/includes/dbtypes/spell.class.php +++ b/includes/dbtypes/spell.class.php @@ -16,7 +16,7 @@ class SpellList extends DBTypeList public static int $type = Type::SPELL; public static string $brickFile = 'spell'; - public static string $dataTable = '?_spell'; + public static string $dataTable = '::spell'; public array $ranks = []; public ?ItemList $relItems = null; public static array $skillLines = array( @@ -102,13 +102,13 @@ class SpellList extends DBTypeList 10 => 4 ); - protected string $queryBase = 'SELECT s.*, s.`id` AS ARRAY_KEY FROM ?_spell s'; + protected string $queryBase = 'SELECT s.*, s.`id` AS ARRAY_KEY FROM ::spell s'; protected array $queryOpts = array( 's' => [['src', 'sr', 'ic', 'ica']], // 6: Type::SPELL - 'ic' => ['j' => ['?_icons ic ON ic.`id` = s.`iconId`', true], 's' => ', ic.`name` AS "iconString"'], - 'ica' => ['j' => ['?_icons ica ON ica.`id` = s.`iconIdAlt`', true], 's' => ', ica.`name` AS "iconStringAlt"'], - 'sr' => ['j' => ['?_spellrange sr ON sr.`id` = s.`rangeId`'], 's' => ', sr.`rangeMinHostile`, sr.`rangeMinFriend`, sr.`rangeMaxHostile`, sr.`rangeMaxFriend`, sr.`name_loc0` AS "rangeText_loc0", sr.`name_loc2` AS "rangeText_loc2", sr.`name_loc3` AS "rangeText_loc3", sr.`name_loc4` AS "rangeText_loc4", sr.`name_loc6` AS "rangeText_loc6", sr.`name_loc8` AS "rangeText_loc8"'], - 'src' => ['j' => ['?_source src ON `type` = 6 AND `typeId` = s.`id`', true], 's' => ', `moreType`, `moreTypeId`, `moreZoneId`, `moreMask`, `src1`, `src2`, `src3`, `src4`, `src5`, `src6`, `src7`, `src8`, `src9`, `src10`, `src11`, `src12`, `src13`, `src14`, `src15`, `src16`, `src17`, `src18`, `src19`, `src20`, `src21`, `src22`, `src23`, `src24`'] + 'ic' => ['j' => ['::icons ic ON ic.`id` = s.`iconId`', true], 's' => ', ic.`name` AS "iconString"'], + 'ica' => ['j' => ['::icons ica ON ica.`id` = s.`iconIdAlt`', true], 's' => ', ica.`name` AS "iconStringAlt"'], + 'sr' => ['j' => ['::spellrange sr ON sr.`id` = s.`rangeId`'], 's' => ', sr.`rangeMinHostile`, sr.`rangeMinFriend`, sr.`rangeMaxHostile`, sr.`rangeMaxFriend`, sr.`name_loc0` AS "rangeText_loc0", sr.`name_loc2` AS "rangeText_loc2", sr.`name_loc3` AS "rangeText_loc3", sr.`name_loc4` AS "rangeText_loc4", sr.`name_loc6` AS "rangeText_loc6", sr.`name_loc8` AS "rangeText_loc8"'], + 'src' => ['j' => ['::source src ON `type` = 6 AND `typeId` = s.`id`', true], 's' => ', `moreType`, `moreTypeId`, `moreZoneId`, `moreMask`, `src1`, `src2`, `src3`, `src4`, `src5`, `src6`, `src7`, `src8`, `src9`, `src10`, `src11`, `src12`, `src13`, `src14`, `src15`, `src16`, `src17`, `src18`, `src19`, `src20`, `src21`, `src22`, `src23`, `src24`'] ); public function __construct(array $conditions = [], array $miscData = []) @@ -125,7 +125,7 @@ class SpellList extends DBTypeList $this->charLevel = $miscData['charLevel']; // post processing - $foo = DB::World()->selectCol('SELECT `perfectItemType` FROM skill_perfect_item_template WHERE `spellId` IN (?a)', $this->getFoundIDs()); + $foo = DB::World()->selectCol('SELECT `perfectItemType` FROM skill_perfect_item_template WHERE `spellId` IN %in', $this->getFoundIDs()); foreach ($this->iterate() as &$_curTpl) { // required for globals @@ -450,7 +450,7 @@ class SpellList extends DBTypeList // TotemCategory if ($_ = $this->curTpl['toolCategory'.$i]) { - $tc = DB::Aowow()->selectRow('SELECT * FROM ?_totemcategory WHERE `id` = ?d', $_); + $tc = DB::Aowow()->selectRow('SELECT * FROM ::totemcategory WHERE `id` = %i', $_); $tools[$i + 1] = array( 'id' => $_, 'name' => Util::localizedString($tc, 'name')); @@ -524,7 +524,7 @@ class SpellList extends DBTypeList 2289 => [2289, 29415, 29418, 29419, 29420, 29421] // Bear - Tauren ); - if ($st = DB::Aowow()->selectRow('SELECT *, `displayIdA` AS "model1", `displayIdH` AS "model2" FROM ?_shapeshiftforms WHERE `id` = ?d', $effMV)) + if ($st = DB::Aowow()->selectRow('SELECT *, `displayIdA` AS "model1", `displayIdH` AS "model2" FROM ::shapeshiftforms WHERE `id` = %i', $effMV)) { foreach ([1, 2] as $j) if (isset($subForms[$st['model'.$j]])) @@ -1391,7 +1391,7 @@ class SpellList extends DBTypeList return [$return, $fSuffix, $fStat]; } - // should probably used only once to create ?_spell. come to think of it, it yields the same results every time.. it absolutely has to! + // should probably used only once to create ::spell. come to think of it, it yields the same results every time.. it absolutely has to! // although it seems to be pretty fast, even on those pesky test-spells with extra complex tooltips (Ron Test Spell X)) public function parseText(string $type = 'description', int $level = MAX_LEVEL) : array { @@ -1403,7 +1403,7 @@ class SpellList extends DBTypeList documentation .. sort of bracket use ${}.x - formulas; .x is optional; x:[0-9] .. max-precision of a floatpoint-result; default: 0 - $[] - conditionals ... like $?condition[true][false]; alternative $?!(cond1|cond2)[true]$?cond3[elseTrue][false]; ?a40120: has aura 40120; ?s40120: knows spell 40120(?) + $[] - conditionals ... like $?condition[true][false]; alternative $?!(cond1|cond2)[true]$?cond3[elseTrue][false]; ?a40120: has aura 40120; ?s40120: knows spell 40120(%s) $<> - variables () - regular use for function-like calls @@ -1493,7 +1493,7 @@ class SpellList extends DBTypeList { if (empty($this->spellVars[$this->id])) { - $spellVars = DB::Aowow()->SelectCell('SELECT `vars` FROM ?_spellvariables WHERE `id` = ?d', $this->curTpl['spellDescriptionVariableId']); + $spellVars = DB::Aowow()->SelectCell('SELECT `vars` FROM ::spellvariables WHERE `id` = %i', $this->curTpl['spellDescriptionVariableId']); $spellVars = explode("\n", $spellVars); foreach ($spellVars as $sv) if (preg_match('/\$(\w*\d*)=(.*)/i', trim($sv), $matches)) @@ -2637,7 +2637,7 @@ class SpellListFilter extends Filter // race if ($_v['ra']) - $parts[] = ['AND', [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL, '!'], ['reqRaceMask', $this->list2Mask([$_v['ra']]), '&']]; + $parts[] = [DB::AND, [['reqRaceMask', ChrRace::MASK_ALL, '&'], ChrRace::MASK_ALL, '!'], ['reqRaceMask', $this->list2Mask([$_v['ra']]), '&']]; // class [list] if ($_v['cl']) @@ -2657,7 +2657,7 @@ class SpellListFilter extends Filter // mechanic if ($_v['me']) - $parts[] = ['OR', ['mechanic', $_v['me']], ['effect1Mechanic', $_v['me']], ['effect2Mechanic', $_v['me']], ['effect3Mechanic', $_v['me']]]; + $parts[] = [DB::OR, ['mechanic', $_v['me']], ['effect1Mechanic', $_v['me']], ['effect2Mechanic', $_v['me']], ['effect3Mechanic', $_v['me']]]; return $parts; } @@ -2695,9 +2695,9 @@ class SpellListFilter extends Filter if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs)) return null; - return ['OR', - ['AND', ['powerType', [POWER_RAGE, POWER_RUNIC_POWER]], ['powerCost', (10 * $crv), $crs]], - ['AND', ['powerType', [POWER_RAGE, POWER_RUNIC_POWER], '!'], ['powerCost', $crv, $crs]] + return [DB::OR, + [DB::AND, ['powerType', [POWER_RAGE, POWER_RUNIC_POWER]], ['powerCost', (10 * $crv), $crs]], + [DB::AND, ['powerType', [POWER_RAGE, POWER_RUNIC_POWER], '!'], ['powerCost', $crv, $crs]] ]; } @@ -2711,7 +2711,7 @@ class SpellListFilter extends Filter return ['src.src'.$_, null, '!']; else if ($_) // any { - $foo = ['OR']; + $foo = [DB::OR]; foreach (self::$enums[$cr] as $bar) if (is_int($bar)) $foo[] = ['src.src'.$bar, null, '!']; @@ -2730,9 +2730,9 @@ class SpellListFilter extends Filter return null; if ($crs) - return ['OR', ['reagent1', 0, '>'], ['reagent2', 0, '>'], ['reagent3', 0, '>'], ['reagent4', 0, '>'], ['reagent5', 0, '>'], ['reagent6', 0, '>'], ['reagent7', 0, '>'], ['reagent8', 0, '>']]; + return [DB::OR, ['reagent1', 0, '>'], ['reagent2', 0, '>'], ['reagent3', 0, '>'], ['reagent4', 0, '>'], ['reagent5', 0, '>'], ['reagent6', 0, '>'], ['reagent7', 0, '>'], ['reagent8', 0, '>']]; else - return ['AND', ['reagent1', 0], ['reagent2', 0], ['reagent3', 0], ['reagent4', 0], ['reagent5', 0], ['reagent6', 0], ['reagent7', 0], ['reagent8', 0]]; + return [DB::AND, ['reagent1', 0], ['reagent2', 0], ['reagent3', 0], ['reagent4', 0], ['reagent5', 0], ['reagent6', 0], ['reagent7', 0], ['reagent8', 0]]; } protected function cbAuraNames(int $cr, int $crs, string $crv) : ?array @@ -2740,7 +2740,7 @@ class SpellListFilter extends Filter if (!$this->checkInput(parent::V_RANGE, [1, self::MAX_SPELL_AURA], $crs)) return null; - return ['OR', ['effect1AuraId', $crs], ['effect2AuraId', $crs], ['effect3AuraId', $crs]]; + return [DB::OR, ['effect1AuraId', $crs], ['effect2AuraId', $crs], ['effect3AuraId', $crs]]; } protected function cbEffectNames(int $cr, int $crs, string $crv) : ?array @@ -2748,7 +2748,7 @@ class SpellListFilter extends Filter if (!$this->checkInput(parent::V_RANGE, [1, self::MAX_SPELL_EFFECT], $crs)) return null; - return ['OR', ['effect1Id', $crs], ['effect2Id', $crs], ['effect3Id', $crs]]; + return [DB::OR, ['effect1Id', $crs], ['effect2Id', $crs], ['effect3Id', $crs]]; } protected function cbInverseFlag(int $cr, int $crs, string $crv, string $field, int $flag) : ?array @@ -2768,9 +2768,9 @@ class SpellListFilter extends Filter return null; if ($crs) - return ['AND', [[$field, $flag, '&'], 0], ['dispelType', SPELL_DAMAGE_CLASS_MAGIC]]; + return [DB::AND, [[$field, $flag, '&'], 0], ['dispelType', SPELL_DAMAGE_CLASS_MAGIC]]; else - return ['OR', [$field, $flag, '&'], ['dispelType', SPELL_DAMAGE_CLASS_MAGIC, '!']]; + return [DB::OR, [$field, $flag, '&'], ['dispelType', SPELL_DAMAGE_CLASS_MAGIC, '!']]; } protected function cbReqFaction(int $cr, int $crs, string $crv) : ?array @@ -2780,11 +2780,11 @@ class SpellListFilter extends Filter // yes 1 => ['reqRaceMask', 0, '!'], // alliance - 2 => ['AND', [['reqRaceMask', ChrRace::MASK_HORDE, '&'], 0], ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']], + 2 => [DB::AND, [['reqRaceMask', ChrRace::MASK_HORDE, '&'], 0], ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&']], // horde - 3 => ['AND', [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], 0], ['reqRaceMask', ChrRace::MASK_HORDE, '&']], + 3 => [DB::AND, [['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], 0], ['reqRaceMask', ChrRace::MASK_HORDE, '&']], // both - 4 => ['AND', ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ['reqRaceMask', ChrRace::MASK_HORDE, '&']], + 4 => [DB::AND, ['reqRaceMask', ChrRace::MASK_ALLIANCE, '&'], ['reqRaceMask', ChrRace::MASK_HORDE, '&']], // no 5 => ['reqRaceMask', 0], default => null @@ -2800,9 +2800,9 @@ class SpellListFilter extends Filter $field = $useInvType ? 'equippedItemInventoryTypeMask' : 'equippedItemSubClassMask'; if ($crs) - return ['AND', ['equippedItemClass', ITEM_CLASS_WEAPON], [$field, $mask, '&']]; + return [DB::AND, ['equippedItemClass', ITEM_CLASS_WEAPON], [$field, $mask, '&']]; else - return ['OR', ['equippedItemClass', ITEM_CLASS_WEAPON, '!'], [[$field, $mask, '&'], 0]]; + return [DB::OR, ['equippedItemClass', ITEM_CLASS_WEAPON, '!'], [[$field, $mask, '&'], 0]]; } /* unused - for reference: attribute flag or cooldown time constraint */ @@ -2812,14 +2812,14 @@ class SpellListFilter extends Filter return null; if ($crs) - return ['AND', + return [DB::AND, [['attributes4', SPELL_ATTR4_NOT_USABLE_IN_ARENA, '&'], 0], - ['OR', ['recoveryTime', 10 * MINUTE * 1000, '<='], ['attributes4', SPELL_ATTR4_USABLE_IN_ARENA, '&']] + [DB::OR, ['recoveryTime', 10 * MINUTE * 1000, '<='], ['attributes4', SPELL_ATTR4_USABLE_IN_ARENA, '&']] ]; else - return ['OR', + return [DB::OR, ['attributes4', SPELL_ATTR4_NOT_USABLE_IN_ARENA, '&'], - ['AND', ['recoveryTime', 10 * MINUTE * 1000, '>'], [['attributes4', SPELL_ATTR4_USABLE_IN_ARENA, '&'], 0]] + [DB::AND, ['recoveryTime', 10 * MINUTE * 1000, '>'], [['attributes4', SPELL_ATTR4_USABLE_IN_ARENA, '&'], 0]] ]; } @@ -2829,9 +2829,9 @@ class SpellListFilter extends Filter return null; if ($crs) // match exact, not as flag - return ['AND', ['attributes1', SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2 | SPELL_ATTR1_CHANNEL_TRACK_TARGET], ['effect1ImplicitTargetA', 21]]; + return [DB::AND, ['attributes1', SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2 | SPELL_ATTR1_CHANNEL_TRACK_TARGET], ['effect1ImplicitTargetA', 21]]; else - return ['OR', ['attributes1', SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2 | SPELL_ATTR1_CHANNEL_TRACK_TARGET, '!'], ['effect1ImplicitTargetA', 21, '!']]; + return [DB::OR, ['attributes1', SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2 | SPELL_ATTR1_CHANNEL_TRACK_TARGET, '!'], ['effect1ImplicitTargetA', 21, '!']]; } protected function cbProficiency(int $cr, int $crs, string $crv) : ?array @@ -2847,16 +2847,16 @@ class SpellListFilter extends Filter case 1: // Weapons foreach (Game::$skillLineMask[-3] as $bit => $_) $skill2Mask |= (1 << $bit); - $skill1Ids = DB::Aowow()->selectCol('SELECT `id` FROM ?_skillline WHERE `typeCat` = 6'); + $skill1Ids = DB::Aowow()->selectCol('SELECT `id` FROM ::skillline WHERE `typeCat` = 6'); break; case 2: // Armor (Proficiencies + Specializations: so for us it's the same) case 3: // Armor Proficiencies - $skill1Ids = DB::Aowow()->selectCol('SELECT `id` FROM ?_skillline WHERE `typeCat` = 8'); + $skill1Ids = DB::Aowow()->selectCol('SELECT `id` FROM ::skillline WHERE `typeCat` = 8'); break; case 4: // Armor Specializations return [0]; // 4.x+ feature where using purely one type of armor increases your primary stat case 5: // Languages - $skill1Ids = DB::Aowow()->selectCol('SELECT `id` FROM ?_skillline WHERE `typeCat` = 10'); + $skill1Ids = DB::Aowow()->selectCol('SELECT `id` FROM ::skillline WHERE `typeCat` = 10'); break; } @@ -2865,7 +2865,7 @@ class SpellListFilter extends Filter $cnd = ['skillLine1', $skill1Ids]; if ($skill2Mask) - $cnd = ['OR', $cnd, ['AND', ['skillLine1', -3], ['skillLine2OrMask', $skill2Mask, '&']]]; + $cnd = [DB::OR, $cnd, [DB::AND, ['skillLine1', -3], ['skillLine2OrMask', $skill2Mask, '&']]]; return $cnd; } diff --git a/includes/dbtypes/title.class.php b/includes/dbtypes/title.class.php index b8cd1cb2..b583a290 100644 --- a/includes/dbtypes/title.class.php +++ b/includes/dbtypes/title.class.php @@ -12,13 +12,13 @@ class TitleList extends DBTypeList public static int $type = Type::TITLE; public static string $brickFile = 'title'; - public static string $dataTable = '?_titles'; + public static string $dataTable = '::titles'; public array $sources = []; - protected string $queryBase = 'SELECT t.*, t.`id` AS ARRAY_KEY FROM ?_titles t'; + protected string $queryBase = 'SELECT t.*, t.`id` AS ARRAY_KEY FROM ::titles t'; protected array $queryOpts = array( 't' => [['src']], // 11: Type::TITLE - 'src' => ['j' => ['?_source src ON `type` = 11 AND `typeId` = t.`id`', true], 's' => ', `src13`, `moreType`, `moreTypeId`'] + 'src' => ['j' => ['::source src ON `type` = 11 AND `typeId` = t.`id`', true], 's' => ', `src13`, `moreType`, `moreTypeId`'] ); public function __construct(array $conditions = [], array $miscData = []) @@ -55,7 +55,7 @@ class TitleList extends DBTypeList public static function getName(int $id) : ?LocString { - if ($n = DB::Aowow()->SelectRow('SELECT `male_loc0`, `male_loc2`, `male_loc3`, `male_loc4`, `male_loc6`, `male_loc8` FROM ?# WHERE `id` = ?d', self::$dataTable, $id)) + if ($n = DB::Aowow()->SelectRow('SELECT `male_loc0`, `male_loc2`, `male_loc3`, `male_loc4`, `male_loc6`, `male_loc8` FROM %n WHERE `id` = %i', self::$dataTable, $id)) return new LocString($n, 'male', fn($x) => trim(str_replace('%s', '', $x))); return null; } diff --git a/includes/dbtypes/user.class.php b/includes/dbtypes/user.class.php index 44f4f83b..18122f6b 100644 --- a/includes/dbtypes/user.class.php +++ b/includes/dbtypes/user.class.php @@ -13,10 +13,10 @@ class UserList extends DBTypeList public static string $dataTable = ''; public static int $contribute = CONTRIBUTE_NONE; - protected string $queryBase = 'SELECT *, a.`id` AS ARRAY_KEY FROM ?_account a'; + protected string $queryBase = 'SELECT *, a.`id` AS ARRAY_KEY FROM ::account a'; protected array $queryOpts = array( 'a' => [['r']], - 'r' => ['j' => ['?_account_reputation r ON r.`userId` = a.`id`', true], 's' => ', IFNULL(SUM(r.`amount`), 0) AS "reputation"', 'g' => 'a.`id`'] + 'r' => ['j' => ['::account_reputation r ON r.`userId` = a.`id`', true], 's' => ', IFNULL(SUM(r.`amount`), 0) AS "reputation"', 'g' => 'a.`id`'] ); public function getJSGlobals(int $addMask = 0) : array @@ -49,7 +49,7 @@ class UserList extends DBTypeList case 2: if ($this->isPremium()) { - if ($av = DB::Aowow()->selectCell('SELECT `id` FROM ?_account_avatars WHERE `userId` = ?d AND `current` = 1 AND `status` <> ?d', $userId, AvatarMgr::STATUS_REJECTED)) + if ($av = DB::Aowow()->selectCell('SELECT `id` FROM ::account_avatars WHERE `userId` = %i AND `current` = 1 AND `status` <> %i', $userId, AvatarMgr::STATUS_REJECTED)) { $data[$this->curTpl['username']]['avatar'] = $this->curTpl['avatar']; $data[$this->curTpl['username']]['avatarmore'] = $av; diff --git a/includes/dbtypes/worldevent.class.php b/includes/dbtypes/worldevent.class.php index d5184f26..399d6083 100644 --- a/includes/dbtypes/worldevent.class.php +++ b/includes/dbtypes/worldevent.class.php @@ -10,13 +10,13 @@ class WorldEventList extends DBTypeList { public static int $type = Type::WORLDEVENT; public static string $brickFile = 'event'; - public static string $dataTable = '?_events'; + public static string $dataTable = '::events'; - protected string $queryBase = 'SELECT e.`holidayId`, e.`cuFlags`, e.`startTime`, e.`endTime`, e.`occurence`, e.`length`, e.`requires`, e.`description` AS "nameINT", e.`id` AS "eventId", e.`id` AS ARRAY_KEY FROM ?_events e'; + protected string $queryBase = 'SELECT e.`holidayId`, e.`cuFlags`, e.`startTime`, e.`endTime`, e.`occurence`, e.`length`, e.`requires`, e.`description` AS "nameINT", e.`id` AS "eventId", e.`id` AS ARRAY_KEY FROM ::events e'; protected array $queryOpts = array( 'e' => [['h', 'ic']], - 'h' => ['j' => ['?_holidays h ON e.`holidayId` = h.`id`', true], 's' => ', h.*', 'o' => '-e.`id` ASC'], - 'ic' => ['j' => ['?_icons ic ON ic.`id` = h.`iconId`', true], 's' => ', ic.`name` AS "iconString"'] + 'h' => ['j' => ['::holidays h ON e.`holidayId` = h.`id`', true], 's' => ', h.*', 'o' => '-e.`id` ASC'], + 'ic' => ['j' => ['::icons ic ON ic.`id` = h.`iconId`', true], 's' => ', ic.`name` AS "iconString"'] ); public function __construct(array $conditions = [], array $miscData = []) @@ -71,9 +71,9 @@ class WorldEventList extends DBTypeList { $row = DB::Aowow()->SelectRow( 'SELECT IFNULL(h.`name_loc0`, e.`description`) AS "name_loc0", h.`name_loc2`, h.`name_loc3`, h.`name_loc4`, h.`name_loc6`, h.`name_loc8` - FROM ?_events e - LEFT JOIN ?_holidays h ON e.`holidayId` = h.`id` - WHERE e.`id` = ?d', + FROM ::events e + LEFT JOIN ::holidays h ON e.`holidayId` = h.`id` + WHERE e.`id` = %i', $id ); diff --git a/includes/dbtypes/zone.class.php b/includes/dbtypes/zone.class.php index f3bc02d7..668eac6e 100644 --- a/includes/dbtypes/zone.class.php +++ b/includes/dbtypes/zone.class.php @@ -12,9 +12,9 @@ class ZoneList extends DBTypeList public static int $type = Type::ZONE; public static string $brickFile = 'zone'; - public static string $dataTable = '?_zones'; + public static string $dataTable = '::zones'; - protected string $queryBase = 'SELECT z.*, z.`id` AS ARRAY_KEY FROM ?_zones z'; + protected string $queryBase = 'SELECT z.*, z.`id` AS ARRAY_KEY FROM ::zones z'; public function __construct(array $conditions = [], array $miscData = []) { diff --git a/includes/defines.php b/includes/defines.php index fb03af09..4075085a 100644 --- a/includes/defines.php +++ b/includes/defines.php @@ -131,7 +131,7 @@ define('AUTH_IPBANNED', 4); define('AUTH_ACC_INACTIVE', 5); define('AUTH_INTERNAL_ERR', 6); -define('AUTH_MODE_SELF', 0); // uses ?_accounts +define('AUTH_MODE_SELF', 0); // uses ::accounts define('AUTH_MODE_REALM', 1); // uses given realm-table define('AUTH_MODE_EXTERNAL', 2); // uses external script @@ -1087,7 +1087,7 @@ define('ENCHANTMENT_TYPE_PRISMATIC_SOCKET', 8); // define('ENCHANT_CONDITION_EQUAL_VALUE', ?); define('ENCHANT_CONDITION_LESS_VALUE', 2); define('ENCHANT_CONDITION_MORE_COMPARE', 3); -// define('ENCHANT_CONDITION_MORE_EQUAL_COMPARE', ?); +// define('ENCHANT_CONDITION_MORE_EQUAL_COMPARE', %s); define('ENCHANT_CONDITION_MORE_VALUE', 5); // define('ENCHANT_CONDITION_NOT_EQUAL_COMPARE', ?); // define('ENCHANT_CONDITION_NOT_EQUAL_VALUE', ?); diff --git a/includes/game/chrstatistics.php b/includes/game/chrstatistics.php index d0874f03..1777e31c 100644 --- a/includes/game/chrstatistics.php +++ b/includes/game/chrstatistics.php @@ -490,7 +490,7 @@ class StatsContainer implements \Countable public function fromDB(int $type, int $typeId, int $fieldFlags = Stat::FLAG_NONE) : self { - foreach (DB::Aowow()->selectRow('SELECT (?#) FROM ?_item_stats WHERE `type` = ?d AND `typeId` = ?d', Stat::getJsonStringsFor($fieldFlags ?: (Stat::FLAG_ITEM | Stat::FLAG_SERVERSIDE)), $type, $typeId) as $key => $amt) + foreach (DB::Aowow()->selectRow('SELECT (%n) FROM ::item_stats WHERE `type` = %i AND `typeId` = %i', Stat::getJsonStringsFor($fieldFlags ?: (Stat::FLAG_ITEM | Stat::FLAG_SERVERSIDE)), $type, $typeId) as $key => $amt) { if ($amt === null) continue; diff --git a/includes/game/loot/lootbycontainer.class.php b/includes/game/loot/lootbycontainer.class.php index df650998..64d287d4 100644 --- a/includes/game/loot/lootbycontainer.class.php +++ b/includes/game/loot/lootbycontainer.class.php @@ -37,7 +37,7 @@ class LootByContainer extends Loot if (!$tableName || !$lootId) return [null, null]; - $rows = DB::World()->select('SELECT * FROM ?# WHERE entry = ?d{ AND groupid = ?d}', $tableName, $lootId, $groupId ?: DBSIMPLE_SKIP); + $rows = DB::World()->selectAssoc('SELECT * FROM %n', $tableName, 'WHERE %if', $groupId, '`groupid` = %i AND', $groupId, '%end `entry` = %i', $lootId); if (!$rows) return [null, null]; @@ -54,9 +54,14 @@ class LootByContainer extends Loot 'groupChance' => 0 ); - if ($entry['QuestRequired']) - foreach (DB::Aowow()->selectCol('SELECT id FROM ?_quests WHERE (`reqSourceItemId1` = ?d OR `reqSourceItemId2` = ?d OR `reqSourceItemId3` = ?d OR `reqSourceItemId4` = ?d OR `reqItemId1` = ?d OR `reqItemId2` = ?d OR `reqItemId3` = ?d OR `reqItemId4` = ?d OR `reqItemId5` = ?d OR `reqItemId6` = ?d) AND (`cuFlags` & ?d) = 0', - $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], $entry['Item'], CUSTOM_EXCLUDE_FOR_LISTVIEW | CUSTOM_UNAVAILABLE) as $questId) + $where = [['(`cuFlags` & %i) = 0', CUSTOM_EXCLUDE_FOR_LISTVIEW | CUSTOM_UNAVAILABLE], [DB::OR, []]]; + for ($i = 1; $i < 5; $i++) + $where[1][1][] = ["`reqSourceItemId$i` = %i", $entry['Item']]; + for ($i = 1; $i < 7; $i++) + $where[1][1][] = ["`reqItemId$i` = %i", $entry['Item']]; + + if ($entry['QuestRequired'] && ($quests = DB::Aowow()->selectCol('SELECT `id` FROM ::quests WHERE %and', $where))) + foreach ($quests as $questId) $cnd->addExternalCondition(Conditions::lootTableToConditionSource($tableName), $lootId . ':' . $entry['Item'], [Conditions::QUESTTAKEN, $questId], true); // TC 'mode' (dynamic loot modifier) diff --git a/includes/game/loot/lootbyitem.class.php b/includes/game/loot/lootbyitem.class.php index f6387a36..ba7a29ce 100644 --- a/includes/game/loot/lootbyitem.class.php +++ b/includes/game/loot/lootbyitem.class.php @@ -59,9 +59,9 @@ class LootByItem extends Loot IF(lt1.`reference` = 0, lt1.`mincount`, 1) AS "min", IF(lt1.`reference` = 0, lt1.`maxcount`, 1) AS "max", IF(lt1.`reference` > 0, lt1.`maxcount`, 1) AS "multiplier" - FROM ?# lt1 - LEFT JOIN ?# lt2 ON lt1.`entry` = lt2.`entry` AND lt1.`groupid` = lt2.`groupid` - WHERE %s + FROM %n lt1 + LEFT JOIN %n lt2 ON lt1.`entry` = lt2.`entry` AND lt1.`groupid` = lt2.`groupid` + WHERE %and GROUP BY lt2.`entry`, lt2.`groupid`'; /** @@ -159,10 +159,10 @@ class LootByItem extends Loot /* get references containing the item */ - $newRefs = DB::World()->select( - sprintf($this->queryTemplate, 'lt1.`item` = ?d AND lt1.`reference` = 0'), + $newRefs = DB::World()->selectAssoc( + $this->queryTemplate, Loot::REFERENCE, Loot::REFERENCE, - $this->entry + [['lt1.`item` = %i', $this->entry], ['lt1.`reference` = 0']] ); /* @@ -179,10 +179,10 @@ class LootByItem extends Loot while ($newRefs) { $curRefs = $newRefs; - $newRefs = DB::World()->select( - sprintf($this->queryTemplate, 'lt1.`reference` IN (?a)'), + $newRefs = DB::World()->selectAssoc( + $this->queryTemplate, Loot::REFERENCE, Loot::REFERENCE, - array_keys($curRefs) + [['lt1.`reference` IN %in', array_keys($curRefs)]] ); $refResults += $this->calcChance($curRefs, array_column($newRefs, 'item')); @@ -199,11 +199,14 @@ class LootByItem extends Loot if ($lootTemplate == Loot::REFERENCE) continue; - $result = $this->calcChance(DB::World()->select( - sprintf($this->queryTemplate, '{lt1.`reference` IN (?a) OR }(lt1.`reference` = 0 AND lt1.`item` = ?d)'), + $where = [[DB::OR, [[DB::AND, [['lt1.`reference` = 0'], ['lt1.`item` = %i', $this->entry]]]]]]; + if ($refResults) + $where[0][1][] = ['lt1.`reference` IN %in', array_keys($refResults)]; + + $result = $this->calcChance(DB::World()->selectAssoc( + $this->queryTemplate, $lootTemplate, $lootTemplate, - $refResults ? array_keys($refResults) : DBSIMPLE_SKIP, - $this->entry + $where )); // do not skip here if $result is empty. Additional loot for spells and quest is added separately @@ -288,10 +291,10 @@ class LootByItem extends Loot if (!$ids) return false; - if ($baseIds = DB::Aowow()->selectCol( - 'SELECT `difficultyEntry1` AS ARRAY_KEY, `id` FROM ?_creature WHERE `difficultyEntry1` IN (?a) UNION - SELECT `difficultyEntry2` AS ARRAY_KEY, `id` FROM ?_creature WHERE `difficultyEntry2` IN (?a) UNION - SELECT `difficultyEntry3` AS ARRAY_KEY, `id` FROM ?_creature WHERE `difficultyEntry3` IN (?a)', + if ($baseIds = DB::Aowow()->selectPairs( + 'SELECT `difficultyEntry1` AS ARRAY_KEY, `id` FROM ::creature WHERE `difficultyEntry1` IN %in UNION + SELECT `difficultyEntry2` AS ARRAY_KEY, `id` FROM ::creature WHERE `difficultyEntry2` IN %in UNION + SELECT `difficultyEntry3` AS ARRAY_KEY, `id` FROM ::creature WHERE `difficultyEntry3` IN %in', $ids, $ids, $ids )) { @@ -336,10 +339,10 @@ class LootByItem extends Loot private function handleSpellLoot(array $ids, array $result) : bool { $conditions = array( - 'OR', - ['AND', ['effect1CreateItemId', $this->entry], ['OR', ['effect1Id', SpellList::EFFECTS_ITEM_CREATE], ['effect1AuraId', SpellList::AURAS_ITEM_CREATE]]], - ['AND', ['effect2CreateItemId', $this->entry], ['OR', ['effect2Id', SpellList::EFFECTS_ITEM_CREATE], ['effect2AuraId', SpellList::AURAS_ITEM_CREATE]]], - ['AND', ['effect3CreateItemId', $this->entry], ['OR', ['effect3Id', SpellList::EFFECTS_ITEM_CREATE], ['effect3AuraId', SpellList::AURAS_ITEM_CREATE]]] + DB::OR, + [DB::AND, ['effect1CreateItemId', $this->entry], [DB::OR, ['effect1Id', SpellList::EFFECTS_ITEM_CREATE], ['effect1AuraId', SpellList::AURAS_ITEM_CREATE]]], + [DB::AND, ['effect2CreateItemId', $this->entry], [DB::OR, ['effect2Id', SpellList::EFFECTS_ITEM_CREATE], ['effect2AuraId', SpellList::AURAS_ITEM_CREATE]]], + [DB::AND, ['effect3CreateItemId', $this->entry], [DB::OR, ['effect3Id', SpellList::EFFECTS_ITEM_CREATE], ['effect3AuraId', SpellList::AURAS_ITEM_CREATE]]] ); if ($ids) $conditions[] = ['id', $ids]; @@ -366,7 +369,7 @@ class LootByItem extends Loot private function handleMailLoot(array $ids, array $result) : bool { // quest part - $conditions = array('OR', + $conditions = array(DB::OR, ['rewardChoiceItemId1', $this->entry], ['rewardChoiceItemId2', $this->entry], ['rewardChoiceItemId3', $this->entry], ['rewardChoiceItemId4', $this->entry], ['rewardChoiceItemId5', $this->entry], ['rewardChoiceItemId6', $this->entry], ['rewardItemId1', $this->entry], ['rewardItemId2', $this->entry], ['rewardItemId3', $this->entry], ['rewardItemId4', $this->entry] ); @@ -385,8 +388,8 @@ class LootByItem extends Loot // achievement part $conditions = array(['itemExtra', $this->entry]); - if ($ar = DB::World()->selectCol('SELECT `ID` FROM achievement_reward WHERE `ItemID` = ?d{ OR `MailTemplateID` IN (?a)}', $this->entry, $ids ?: DBSIMPLE_SKIP)) - array_push($conditions, ['id', $ar], 'OR'); + if ($ar = DB::World()->selectCol('SELECT `ID` FROM achievement_reward WHERE %if', $ids, '`MailTemplateID` IN %in OR %end', $ids, '`ItemID` = %i', $this->entry)) + array_push($conditions, ['id', $ar], DB::OR); $achievements = new AchievementList($conditions); if (!$achievements->error) diff --git a/includes/game/misc.php b/includes/game/misc.php index 9ccbb91a..11cc6ab1 100644 --- a/includes/game/misc.php +++ b/includes/game/misc.php @@ -109,9 +109,9 @@ class Game ); /* why: - Because petSkills (and ranged weapon skills) are the only ones with more than two skillLines attached. Because Left Joining ?_spell with ?_skillLineability causes more trouble than it has uses. + Because petSkills (and ranged weapon skills) are the only ones with more than two skillLines attached. Because Left Joining ::spell with ::skillLineability causes more trouble than it has uses. Because this is more or less the only reaonable way to fit all that information into one database field, so.. - .. the indizes of this array are bits of skillLine2OrMask in ?_spell if skillLineId1 is negative + .. the indizes of this array are bits of skillLine2OrMask in ::spell if skillLineId1 is negative */ public static array $skillLineMask = array( // idx => [familyId, skillLineId] -1 => array( // Pets (Hunter) @@ -174,8 +174,8 @@ class Game // note: omits required spell and chance in skill_discovery_template $data = array_merge( - DB::World()->selectCol('SELECT spellId FROM spell_learn_spell WHERE entry IN (?a)', $lookup), - DB::World()->selectCol('SELECT spellId FROM skill_discovery_template WHERE reqSpell IN (?a)', $lookup), + DB::World()->selectCol('SELECT spellId FROM spell_learn_spell WHERE entry IN %in', $lookup), + DB::World()->selectCol('SELECT spellId FROM skill_discovery_template WHERE reqSpell IN %in', $lookup), $extraIds ); @@ -190,7 +190,7 @@ class Game $pages = []; while ($ptId) { - if ($row = DB::World()->selectRow('SELECT ptl.`Text` AS Text_loc?d, pt.* FROM page_text pt LEFT JOIN page_text_locale ptl ON pt.`ID` = ptl.`ID` AND locale = ? WHERE pt.`ID` = ?d', Lang::getLocale()->value, Lang::getLocale()->json(), $ptId)) + if ($row = DB::World()->selectRow('SELECT ptl.`Text` AS Text_loc%i, pt.* FROM page_text pt LEFT JOIN page_text_locale ptl ON pt.`ID` = ptl.`ID` AND locale = %s WHERE pt.`ID` = %i', Lang::getLocale()->value, Lang::getLocale()->json(), $ptId)) { $ptId = $row['NextPageID']; $pages[] = Util::localizedString($row, 'Text'); @@ -210,20 +210,21 @@ class Game $quotes = []; $soundIds = []; - $quoteSrc = DB::World()->select( + $quoteSrc = DB::World()->selectAssoc( 'SELECT ct.`GroupID` AS ARRAY_KEY, ct.`ID` AS ARRAY_KEY2, ct.`Type` AS "talkType", ct.TextRange AS "range", IFNULL(bct.`LanguageID`, ct.`Language`) AS "lang", IFNULL(NULLIF(bct.`Text`, ""), IFNULL(NULLIF(bct.`Text1`, ""), IFNULL(ct.`Text`, ""))) AS "text_loc0", - { IFNULL(NULLIF(bctl.`Text`, ""), IFNULL(NULLIF(bctl.`Text1`, ""), IFNULL(ctl.`Text`, ""))) AS text_loc?d, } + %if', Lang::getLocale()->value, + 'IFNULL(NULLIF(bctl.`Text`, ""), IFNULL(NULLIF(bctl.`Text1`, ""), IFNULL(ctl.`Text`, ""))) AS text_loc%i,', Lang::getLocale()->value, + '%end IF(bct.`SoundEntriesID` > 0, bct.`SoundEntriesID`, ct.`Sound`) AS "soundId" FROM creature_text ct - { LEFT JOIN creature_text_locale ctl ON ct.`CreatureID` = ctl.`CreatureID` AND ct.`GroupID` = ctl.`GroupID` AND ct.`ID` = ctl.`ID` AND ctl.`Locale` = ? } LEFT JOIN broadcast_text bct ON ct.`BroadcastTextId` = bct.`ID` - { LEFT JOIN broadcast_text_locale bctl ON ct.`BroadcastTextId` = bctl.`ID` AND bctl.`locale` = ? } - WHERE ct.`CreatureID` = ?d', - Lang::getLocale()->value ?: DBSIMPLE_SKIP, - Lang::getLocale()->value ? Lang::getLocale()->json() : DBSIMPLE_SKIP, - Lang::getLocale()->value ? Lang::getLocale()->json() : DBSIMPLE_SKIP, + %if', Lang::getLocale()->value, + 'LEFT JOIN creature_text_locale ctl ON ct.`CreatureID` = ctl.`CreatureID` AND ct.`GroupID` = ctl.`GroupID` AND ct.`ID` = ctl.`ID` AND ctl.`Locale` = %s', Lang::getLocale()->json(), + 'LEFT JOIN broadcast_text_locale bctl ON ct.`BroadcastTextId` = bctl.`ID` AND bctl.`locale` = %s', Lang::getLocale()->json(), + '%end + WHERE ct.`CreatureID` = %i', $creatureId ); @@ -332,7 +333,7 @@ class Game public static function getEnchantmentCondition(int $conditionId, bool $interactive = false) : string { - $gemCnd = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantmentcondition WHERE `id` = ?d', $conditionId); + $gemCnd = DB::Aowow()->selectRow('SELECT * FROM ::itemenchantmentcondition WHERE `id` = %i', $conditionId); if (!$gemCnd) return ''; diff --git a/includes/game/worldposition.class.php b/includes/game/worldposition.class.php index 00d4d399..df13aaf6 100644 --- a/includes/game/worldposition.class.php +++ b/includes/game/worldposition.class.php @@ -68,7 +68,7 @@ abstract class WorldPosition // spawn does not really match on a map, but we need at least one result if (!$result) { - usort($points, fn ($a, $b) => $a['dist'] <=> $b['dist']); + usort($points, fn($a, $b) => $a['dist'] <=> $b['dist']); $result = [1.0, $points[0]]; } @@ -82,25 +82,25 @@ abstract class WorldPosition switch ($type) { case Type::NPC: - $result = DB::World()->select('SELECT `guid` AS ARRAY_KEY, `id`, `map` AS `mapId`, `position_x` AS `posX`, `position_y` AS `posY` FROM creature WHERE `guid` IN (?a)', $guids); + $result = DB::World()->selectAssoc('SELECT `guid` AS ARRAY_KEY, `id`, `map` AS `mapId`, `position_x` AS `posX`, `position_y` AS `posY` FROM creature WHERE `guid` IN %in', $guids); break; case Type::OBJECT: - $result = DB::World()->select('SELECT `guid` AS ARRAY_KEY, `id`, `map` AS `mapId`, `position_x` AS `posX`, `position_y` AS `posY` FROM gameobject WHERE `guid` IN (?a)', $guids); + $result = DB::World()->selectAssoc('SELECT `guid` AS ARRAY_KEY, `id`, `map` AS `mapId`, `position_x` AS `posX`, `position_y` AS `posY` FROM gameobject WHERE `guid` IN %in', $guids); break; case Type::SOUND: - $result = DB::AoWoW()->select('SELECT `id` AS ARRAY_KEY, `soundId` AS `id`, `mapId`, `posX`, `posY` FROM ?_soundemitters WHERE `id` IN (?a)', $guids); + $result = DB::AoWoW()->selectAssoc('SELECT `id` AS ARRAY_KEY, `soundId` AS `id`, `mapId`, `posX`, `posY` FROM ::soundemitters WHERE `id` IN %in', $guids); break; case Type::ZONE: - $result = DB::Aowow()->select('SELECT -`id` AS ARRAY_KEY, `id`, `parentMapId` AS `mapId`, `parentX` AS `posX`, `parentY` AS `posY` FROM ?_zones WHERE -`id` IN (?a)', $guids); + $result = DB::Aowow()->selectAssoc('SELECT -`id` AS ARRAY_KEY, `id`, `parentMapId` AS `mapId`, `parentX` AS `posX`, `parentY` AS `posY` FROM ::zones WHERE -`id` IN %in', $guids); break; case Type::AREATRIGGER: $result = []; if ($base = array_filter($guids, fn($x) => $x > 0)) - $result = array_replace($result, DB::AoWoW()->select('SELECT `id` AS ARRAY_KEY, `id`, `mapId`, `posX`, `posY` FROM ?_areatrigger WHERE `id` IN (?a)', $base)); + $result = array_replace($result, DB::AoWoW()->selectAssoc('SELECT `id` AS ARRAY_KEY, `id`, `mapId`, `posX`, `posY` FROM ::areatrigger WHERE `id` IN %in', $base)); if ($endpoints = array_filter($guids, fn($x) => $x < 0)) - $result = array_replace($result, DB::World()->select( - 'SELECT -`ID` AS ARRAY_KEY, ID AS `id`, `target_map` AS `mapId`, `target_position_x` AS `posX`, `target_position_y` AS `posY` FROM areatrigger_teleport WHERE -`id` IN (?a) UNION - SELECT -`entryorguid` AS ARRAY_KEY, entryorguid AS `id`, `action_param1` AS `mapId`, `target_x` AS `posX`, `target_y` AS `posY` FROM smart_scripts WHERE -`entryorguid` IN (?a) AND `source_type` = ?d AND `action_type` = ?d', + $result = array_replace($result, DB::World()->selectAssoc( + 'SELECT -`ID` AS ARRAY_KEY, ID AS `id`, `target_map` AS `mapId`, `target_position_x` AS `posX`, `target_position_y` AS `posY` FROM areatrigger_teleport WHERE -`id` IN %in UNION + SELECT -`entryorguid` AS ARRAY_KEY, entryorguid AS `id`, `action_param1` AS `mapId`, `target_x` AS `posX`, `target_y` AS `posY` FROM smart_scripts WHERE -`entryorguid` IN %in AND `source_type` = %i AND `action_type` = %i', $endpoints, $endpoints, SmartAI::SRC_TYPE_AREATRIGGER, SmartAction::ACTION_TELEPORT )); break; @@ -160,14 +160,14 @@ abstract class WorldPosition } // sort by srcPrio DESC (primary), dist ASC (secondary) - usort($points, fn ($a, $b) => ($b['srcPrio'] <=> $a['srcPrio']) ?: ($a['dist'] <=> $b['dist'])); + usort($points, fn($a, $b) => ($b['srcPrio'] <=> $a['srcPrio']) ?: ($a['dist'] <=> $b['dist'])); return $points; } private static function initZoneMaps(int $mapId) : void { - self::$zoneMapCache[$mapId] = DB::Aowow()->select( + self::$zoneMapCache[$mapId] = DB::Aowow()->selectAssoc( 'SELECT x.`id`, x.`areaId`, @@ -176,16 +176,16 @@ abstract class WorldPosition IF(useDM.`id` IS NOT NULL OR x.`defaultDungeonMapId` < 0, 1, 0) AS `srcPrio`, IF(multiDM.`id` IS NOT NULL OR x.`defaultDungeonMapId` < 0, 1, 0) AS `multifloor` FROM - (SELECT 0 AS `id`, `areaId`, `mapId`, `right` AS `minY`, `left` AS `maxY`, `top` AS `maxX`, `bottom` AS `minX`, 0 AS `floor`, 0 AS `worldMapAreaId`, `defaultDungeonMapId` FROM ?_worldmaparea wma UNION - SELECT dm.`id`, `areaId`, wma.`mapId`, `minY`, `maxY`, `maxX`, `minX`, `floor`, `worldMapAreaId`, `defaultDungeonMapId` FROM ?_worldmaparea wma - JOIN ?_dungeonmap dm ON dm.`mapId` = wma.`mapId` WHERE wma.`mapId` NOT IN (0, 1, 530, 571) OR wma.`areaId` = 4395) x + (SELECT 0 AS `id`, `areaId`, `mapId`, `right` AS `minY`, `left` AS `maxY`, `top` AS `maxX`, `bottom` AS `minX`, 0 AS `floor`, 0 AS `worldMapAreaId`, `defaultDungeonMapId` FROM aowow_worldmaparea wma UNION + SELECT dm.`id`, `areaId`, wma.`mapId`, `minY`, `maxY`, `maxX`, `minX`, `floor`, `worldMapAreaId`, `defaultDungeonMapId` FROM aowow_worldmaparea wma + JOIN aowow_dungeonmap dm ON dm.`mapId` = wma.`mapId` WHERE wma.`mapId` NOT IN (0, 1, 530, 571) OR wma.`areaId` = 4395) x LEFT JOIN - ?_dungeonmap useDM ON useDM.`mapId` = x.`mapId` AND useDM.`worldMapAreaId` = x.`worldMapAreaId` AND useDM.`floor` = x.`floor` AND useDM.`worldMapAreaId` > 0 + aowow_dungeonmap useDM ON useDM.`mapId` = x.`mapId` AND useDM.`worldMapAreaId` = x.`worldMapAreaId` AND useDM.`floor` = x.`floor` AND useDM.`worldMapAreaId` > 0 LEFT JOIN - ?_dungeonmap multiDM ON multiDM.`mapId` = x.`mapId` AND multiDM.`worldMapAreaId` = x.`worldMapAreaId` AND multiDM.`floor` <> x.`floor` AND multiDM.`worldMapAreaId` > 0 + aowow_dungeonmap multiDM ON multiDM.`mapId` = x.`mapId` AND multiDM.`worldMapAreaId` = x.`worldMapAreaId` AND multiDM.`floor` <> x.`floor` AND multiDM.`worldMapAreaId` > 0 WHERE - x.`mapId` = ?d AND x.`areaId` <> 0 AND - x.`minX` <> 0 AND x.`maxX` <> 0 AND x.`minY` <> 0 AND x.`maxY` + x.`mapId` = %i AND x.`areaId` <> 0 AND + x.`minX` <> 0 AND x.`maxX` <> 0 AND x.`minY` <> 0 AND x.`maxY` <> 0 GROUP BY x.`id`, x.`areaId`', $mapId diff --git a/includes/kernel.php b/includes/kernel.php index fafe7593..344ddfcd 100644 --- a/includes/kernel.php +++ b/includes/kernel.php @@ -34,8 +34,8 @@ require_once 'includes/defines.php'; require_once 'includes/locale.class.php'; require_once 'localization/lang.class.php'; require_once 'localization/datetime.class.php'; -require_once 'includes/libs/DbSimple/Generic.php'; // Libraray: http://en.dklab.ru/lib/DbSimple (using variant: https://github.com/ivan1986/DbSimple/tree/master) -require_once 'includes/database.class.php'; // wrap DBSimple +require_once 'includes/libs/autoload.php'; // Composer libraries +require_once 'includes/database.php'; // wrap dg/dibi (https://https://dibi.nette.org/) require_once 'includes/utilities.php'; // helper functions require_once 'includes/type.class.php'; // DB types storage and factory require_once 'includes/cfg.class.php'; // Config holder @@ -133,6 +133,10 @@ set_error_handler(function(int $errNo, string $errStr, string $errFile, int $err if (strstr($errStr, 'mysqli_connect') && $errNo == E_WARNING) return true; + // do not log XDebug shenanigans + if (strstr($errFile, 'xdebug://')) + return true; + // we do not log deprecation notices if ($errNo & (E_DEPRECATED | E_USER_DEPRECATED)) return true; @@ -159,12 +163,12 @@ set_error_handler(function(int $errNo, string $errStr, string $errFile, int $err $_POST['c_password'] = '******'; if (DB::isConnected(DB_AOWOW)) - DB::Aowow()->query('INSERT INTO ?_errors (`date`, `version`, `phpError`, `file`, `line`, `query`, `post`, `userGroups`, `message`) VALUES (UNIX_TIMESTAMP(), ?d, ?d, ?, ?d, ?, ?, ?d, ?) ON DUPLICATE KEY UPDATE `date` = UNIX_TIMESTAMP()', + DB::Aowow()->qry('INSERT INTO ::errors (`date`, `version`, `phpError`, `file`, `line`, `query`, `post`, `userGroups`, `message`) VALUES (UNIX_TIMESTAMP(), %i, %i, %s, %i, %s, %s, %i, %s) ON DUPLICATE KEY UPDATE `date` = UNIX_TIMESTAMP()', AOWOW_REVISION, $errNo, $errFile, $errLine, CLI ? 'CLI' : substr($_SERVER['QUERY_STRING'] ?? '', 0, 250), empty($_POST) ? '' : http_build_query($_POST), User::$groups, $errStr ); $logMsg = $errName.' - '.$errStr.' @ '.$errFile. ':'.$errLine; - if (CLI && class_exists('CLI')) + if (CLI && class_exists(__NAMESPACE__.'\CLI')) CLI::write($logMsg, $logLevel); else if (CLI) fwrite(STDERR, $logMsg); @@ -183,7 +187,7 @@ set_exception_handler(function (\Throwable $e) : void $_POST['c_password'] = '******'; if (DB::isConnected(DB_AOWOW)) - DB::Aowow()->query('INSERT INTO ?_errors (`date`, `version`, `phpError`, `file`, `line`, `query`, `post`, `userGroups`, `message`) VALUES (UNIX_TIMESTAMP(), ?d, ?d, ?, ?d, ?, ?, ?d, ?) ON DUPLICATE KEY UPDATE `date` = UNIX_TIMESTAMP()', + DB::Aowow()->qry('INSERT INTO ::errors (`date`, `version`, `phpError`, `file`, `line`, `query`, `post`, `userGroups`, `message`) VALUES (UNIX_TIMESTAMP(), %i, %i, %s, %i, %s, %s, %i, %s) ON DUPLICATE KEY UPDATE `date` = UNIX_TIMESTAMP()', AOWOW_REVISION, $e->getCode(), $e->getFile(), $e->getLine(), CLI ? 'CLI' : substr($_SERVER['QUERY_STRING'] ?? '', 0, 250), empty($_POST) ? '' : http_build_query($_POST), User::$groups, $e->getMessage() ); @@ -211,7 +215,7 @@ register_shutdown_function(function() : void $_POST['c_password'] = '******'; if (DB::isConnected(DB_AOWOW)) - DB::Aowow()->query('INSERT INTO ?_errors (`date`, `version`, `phpError`, `file`, `line`, `query`, `post`, `userGroups`, `message`) VALUES (UNIX_TIMESTAMP(), ?d, ?d, ?, ?d, ?, ?, ?d, ?) ON DUPLICATE KEY UPDATE `date` = UNIX_TIMESTAMP()', + DB::Aowow()->qry('INSERT INTO ::errors (`date`, `version`, `phpError`, `file`, `line`, `query`, `post`, `userGroups`, `message`) VALUES (UNIX_TIMESTAMP(), %i, %i, %s, %i, %s, %s, %i, %s) ON DUPLICATE KEY UPDATE `date` = UNIX_TIMESTAMP()', AOWOW_REVISION, $e['type'], $e['file'], $e['line'], CLI ? 'CLI' : substr($_SERVER['QUERY_STRING'] ?? '', 0, 250), empty($_POST) ? '' : http_build_query($_POST), User::$groups, $e['message'] ); @@ -279,20 +283,6 @@ if (!CLI) Lang::load($loc); else Lang::load(User::$preferedLoc); - - // set up some logging (some queries will execute before we init the user and load the config) - if (Cfg::get('DEBUG') >= LOG_LEVEL_INFO && User::isInGroup(U_GROUP_DEV | U_GROUP_ADMIN)) - { - DB::Aowow()->setLogger(DB::profiler(...)); - DB::World()->setLogger(DB::profiler(...)); - if (DB::isConnected(DB_AUTH)) - DB::Auth()->setLogger(DB::profiler(...)); - - if (!empty($AoWoWconf['characters'])) - foreach ($AoWoWconf['characters'] as $idx => $__) - if (DB::isConnected(DB_CHARACTERS . $idx)) - DB::Characters($idx)->setLogger(DB::profiler(...)); - } } ?> diff --git a/includes/libs/DbSimple/CacherImpl.php b/includes/libs/DbSimple/CacherImpl.php deleted file mode 100644 index 986cb130..00000000 --- a/includes/libs/DbSimple/CacherImpl.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/** - * Created by JetBrains PhpStorm. - * User: sib - * Date: 14.10.13 - * Time: 17:40 - * To change this template use File | Settings | File Templates. - */ - -class CacherImpl implements Zend_Cache_Backend_Interface { - - protected $callback; - - public function __construct($callback) { - if ( is_callable($callback) ) { - $this->callback = $callback; - } else { - $this->callback = $this->callbackDummy; - } - } - - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()) {} - - public function remove($id) {} - - public function test($id) {} - - public function save($data, $id, $tags = array(), $specificLifetime = false) - { - return call_user_func($this->callback, $id, $data); - } - - public function load($id, $doNotTestCacheValidity = false) - { - return call_user_func($this->callback, $id); - } - - public function setDirectives($directives) {} - - protected function callbackDummy($k, $v) - { - return null; - } - -} // CacherImpl class \ No newline at end of file diff --git a/includes/libs/DbSimple/Connect.php b/includes/libs/DbSimple/Connect.php deleted file mode 100644 index b9d19c62..00000000 --- a/includes/libs/DbSimple/Connect.php +++ /dev/null @@ -1,261 +0,0 @@ -<?php - -/** - * Используйте константу DBSIMPLE_SKIP в качестве подстановочного значения чтобы пропустить опцональный SQL блок. - */ -define('DBSIMPLE_SKIP', log(0)); -/** - * Имена специализированных колонок в резальтате, - * которые используются как ключи в результирующем массиве - */ -define('DBSIMPLE_ARRAY_KEY', 'ARRAY_KEY'); // hash-based resultset support -define('DBSIMPLE_PARENT_KEY', 'PARENT_KEY'); // forrest-based resultset support - -/** - * Класс обертка для DbSimple - * - * <br>нужен для ленивой инициализации коннекта к базе - * - * @package DbSimple - * @method mixed transaction(string $mode=null) - * @method mixed commit() - * @method mixed rollback() - * @method mixed select(string $query [, $arg1] [,$arg2] ...) - * @method mixed selectRow(string $query [, $arg1] [,$arg2] ...) - * @method array selectCol(string $query [, $arg1] [,$arg2] ...) - * @method string selectCell(string $query [, $arg1] [,$arg2] ...) - * @method mixed query(string $query [, $arg1] [,$arg2] ...) - * @method string escape(mixed $s, bool $isIdent=false) - * @method DbSimple_SubQuery subquery(string $query [, $arg1] [,$arg2] ...) - * @method callback setLogger(callback $logger) - * @method callback setCacher(callback $cacher) - * @method string setIdentPrefix($prx) - * @method string setCachePrefix($prx) - */ -class DbSimple_Connect -{ - /** @var DbSimple_Generic_Database База данных */ - protected $DbSimple; - /** @var string DSN подключения */ - protected $DSN; - /** @var string Тип базы данных */ - protected $shema; - /** @var array Что выставить при коннекте */ - protected $init; - /** @var integer код ошибки */ - public $error = null; - /** @var string сообщение об ошибке */ - public $errmsg = null; - - /** - * Конструктор только запоминает переданный DSN - * создание класса и коннект происходит позже - * - * @param string $dsn DSN строка БД - */ - public function __construct($dsn) - { - $this->DbSimple = null; - $this->DSN = $dsn; - $this->init = array(); - $this->shema = ucfirst(substr($dsn, 0, strpos($dsn, ':'))); - } - - /** - * Взять базу из пула коннектов - * - * @param string $dsn DSN строка БД - * @return DbSimple_Connect - */ - public static function get($dsn) - { - static $pool = array(); - return isset($pool[$dsn]) ? $pool[$dsn] : $pool[$dsn] = new self($dsn); - } - - /** - * Возвращает тип базы данных - * - * @return string имя типа БД - */ - public function getShema() - { - return $this->shema; - } - - /** - * Коннект при первом запросе к базе данных - */ - public function __call($method, $params) - { - if ($this->DbSimple === null) - $this->connect($this->DSN); - return call_user_func_array(array(&$this->DbSimple, $method), $params); - } - - /** - * mixed selectPage(int &$total, string $query [, $arg1] [,$arg2] ...) - * Функцию нужно вызвать отдельно из-за передачи по ссылке - */ - public function selectPage(&$total, $query) - { - if ($this->DbSimple === null) - $this->connect($this->DSN); - $args = func_get_args(); - $args[0] = &$total; - return call_user_func_array(array(&$this->DbSimple, 'selectPage'), $args); - } - - /** - * Подключение к базе данных - * @param string $dsn DSN строка БД - */ - protected function connect($dsn) - { - $parsed = $this->parseDSN($dsn); - if (!$parsed) - $this->errorHandler('Ошибка разбора строки DSN', $dsn); - if (!isset($parsed['scheme'])) - $this->errorHandler('Невозможно загрузить драйвер базы данных', $parsed); - $this->shema = ucfirst($parsed['scheme']); - require_once __DIR__.'/'.$this->shema.'.php'; - $class = 'DbSimple_'.$this->shema; - $this->DbSimple = new $class($parsed); - $this->errmsg = &$this->DbSimple->errmsg; - $this->error = &$this->DbSimple->error; - $prefix = isset($parsed['prefix']) ? $parsed['prefix'] : ($this->_identPrefix ? $this->_identPrefix : false); - if ($prefix) - $this->DbSimple->setIdentPrefix($prefix); - if ($this->_cachePrefix) $this->DbSimple->setCachePrefix($this->_cachePrefix); - if ($this->_cacher) $this->DbSimple->setCacher($this->_cacher); - if ($this->_logger) $this->DbSimple->setLogger($this->_logger); - $this->DbSimple->setErrorHandler($this->errorHandler!==null ? $this->errorHandler : array(&$this, 'errorHandler')); - //выставление переменных - foreach($this->init as $query) - call_user_func_array(array(&$this->DbSimple, 'query'), $query); - $this->init = array(); - } - - /** - * Функция обработки ошибок - стандартный обработчик - * Все вызовы без @ прекращают выполнение скрипта - * - * @param string $msg Сообщение об ошибке - * @param array $info Подробная информация о контексте ошибки - */ - public function errorHandler($msg, $info) - { - // Если использовалась @, ничего не делать. - if (!error_reporting()) return; - // Выводим подробную информацию об ошибке. - echo "SQL Error: $msg<br><pre>"; - print_r($info); - echo "</pre>"; - exit(); - } - - /** - * Выставляет запрос для инициализации - * - * @param string $query запрос - */ - public function addInit(...$args) - { - if ($this->DbSimple !== null) - return call_user_func_array(array(&$this->DbSimple, 'query'), $args); - $this->init[] = $args; - } - - /** - * Устанавливает новый обработчик ошибок - * Обработчик получает 2 аргумента: - * - сообщение об ошибке - * - массив (код, сообщение, запрос, контекст) - * - * @param callback|null|false $handler обработчик ошибок - * <br> null - по умолчанию - * <br> false - отключен - * @return callback|null|false предыдущий обработчик - */ - public function setErrorHandler($handler) - { - $prev = $this->errorHandler; - $this->errorHandler = $handler; - if ($this->DbSimple) - $this->DbSimple->setErrorHandler($handler); - return $prev; - } - - /** @var callback обработчик ошибок */ - private $errorHandler = null; - private $_cachePrefix = ''; - private $_identPrefix = null; - private $_logger = null; - private $_cacher = null; - - /** - * callback setLogger(callback $logger) - * Set query logger called before each query is executed. - * Returns previous logger. - */ - public function setLogger($logger) - { - $prev = $this->_logger; - $this->_logger = $logger; - if ($this->DbSimple) - $this->DbSimple->setLogger($logger); - return $prev; - } - - /** - * callback setCacher(callback $cacher) - * Set cache mechanism called during each query if specified. - * Returns previous handler. - */ - public function setCacher(Zend_Cache_Backend_Interface $cacher=null) - { - $prev = $this->_cacher; - $this->_cacher = $cacher; - if ($this->DbSimple) - $this->DbSimple->setCacher($cacher); - return $prev; - } - - /** - * string setIdentPrefix($prx) - * Set identifier prefix used for $_ placeholder. - */ - public function setIdentPrefix($prx) - { - $old = $this->_identPrefix; - if ($prx !== null) $this->_identPrefix = $prx; - if ($this->DbSimple) - $this->DbSimple->setIdentPrefix($prx); - return $old; - } - - /** - * string setCachePrefix($prx) - * Set cache prefix used in key caclulation. - */ - public function setCachePrefix($prx) - { - $old = $this->_cachePrefix; - if ($prx !== null) $this->_cachePrefix = $prx; - if ($this->DbSimple) - $this->DbSimple->setCachePrefix($prx); - return $old; - } - - /** - * Разбирает строку DSN в массив параметров подключения к базе - * - * @param string $dsn строка DSN для разбора - * @return array Параметры коннекта - */ - protected function parseDSN($dsn) - { - return DbSimple_Generic::parseDSN($dsn); - } - -} diff --git a/includes/libs/DbSimple/Database.php b/includes/libs/DbSimple/Database.php deleted file mode 100644 index d6a6a5bf..00000000 --- a/includes/libs/DbSimple/Database.php +++ /dev/null @@ -1,1406 +0,0 @@ -<?php - -/** - * DbSimple_Database: Base class for all databases. - * (C) Dk Lab, http://en.dklab.ru - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * See http://www.gnu.org/copyleft/lesser.html - * - * Use static DbSimple_Generic::connect($dsn) call if you don't know - * database type and parameters, but have its DSN. - * - * Additional keys can be added by appending a URI query string to the - * end of the DSN. - * - * The format of the supplied DSN is in its fullest form: - * phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true - * - * Most variations are allowed: - * phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644 - * phptype://username:password@hostspec/database_name - * phptype://username:password@hostspec - * phptype://username@hostspec - * phptype://hostspec/database - * phptype://hostspec - * phptype(dbsyntax) - * phptype - * - * Parsing code is partially grabbed from PEAR DB class, - * initial author: Tomas V.V.Cox <cox@idecnet.com>. - * - * Contains 3 classes: - * - DbSimple_Database: common database methods - * - DbSimple_Blob: common BLOB support - * - DbSimple_LastError: error reporting and tracking - * - * Special result-set fields: - * - ARRAY_KEY* ("*" means "anything") - * - PARENT_KEY - * - * Transforms: - * - GET_ATTRIBUTES - * - CALC_TOTAL - * - GET_TOTAL - * - UNIQ_KEY - * - * Query attributes: - * - BLOB_OBJ - * - CACHE - * - * @author Dmitry Koterov, http://forum.dklab.ru/users/DmitryKoterov/ - * @author Konstantin Zhinko, http://forum.dklab.ru/users/KonstantinGinkoTit/ - * @author Ivan Borzenkov, http://forum.dklab.ru/users/Ivan1986/ - * - * @version 2.x $Id$ - */ - -/** - * Use this constant as placeholder value to skip optional SQL block [...]. - */ -if (!defined('DBSIMPLE_SKIP')) - define('DBSIMPLE_SKIP', log(0)); - -/** - * Names of special columns in result-set which is used - * as array key (or karent key in forest-based resultsets) in - * resulting hash. - */ -if (!defined('DBSIMPLE_ARRAY_KEY')) - define('DBSIMPLE_ARRAY_KEY', 'ARRAY_KEY'); // hash-based resultset support -if (!defined('DBSIMPLE_PARENT_KEY')) - define('DBSIMPLE_PARENT_KEY', 'PARENT_KEY'); // forrest-based resultset support - - -if ( !interface_exists('Zend_Cache_Backend_Interface', false) ) { - require_once __DIR__ . '/Zend/Cache.php'; - require_once __DIR__ . '/Zend/Cache/Backend/Interface.php'; -} - -require_once __DIR__ . '/CacherImpl.php'; - - -/** - * - * Base class for all databases. - * Can create transactions and new BLOBs, parse DSNs. - * - * Logger is COMMON for multiple transactions. - * Error handler is private for each transaction and database. - */ -abstract class DbSimple_Database extends DbSimple_LastError -{ - private $attributes; - - /** - * Public methods. - */ - - /** - * object blob($blob_id) - * Create new blob - */ - public function blob($blob_id = null) - { - $this->_resetLastError(); - return $this->_performNewBlob($blob_id); - } - - /** - * void transaction($mode) - * Create new transaction. - */ - public function transaction($mode=null) - { - $this->_resetLastError(); - $this->_logQuery('-- START TRANSACTION '.$mode); - return $this->_performTransaction($mode); - } - - /** - * mixed commit() - * Commit the transaction. - */ - public function commit() - { - $this->_resetLastError(); - $this->_logQuery('-- COMMIT'); - return $this->_performCommit(); - } - - /** - * mixed rollback() - * Rollback the transaction. - */ - public function rollback() - { - $this->_resetLastError(); - $this->_logQuery('-- ROLLBACK'); - return $this->_performRollback(); - } - - /** - * mixed select(string $query [, $arg1] [,$arg2] ...) - * Execute query and return the result. - */ - public function select(...$args) - { - $total = false; - return $this->_query($args, $total); - } - - /** - * mixed selectPage(int &$total, string $query [, $arg1] [,$arg2] ...) - * Execute query and return the result. - * Total number of found rows (independent to LIMIT) is returned in $total - * (in most cases second query is performed to calculate $total). - */ - public function selectPage(&$total, ...$args) - { - $total = true; - return $this->_query($args, $total); - } - - /** - * hash selectRow(string $query [, $arg1] [,$arg2] ...) - * Return the first row of query result. - * On errors return false and set last error. - * If no one row found, return array()! It is useful while debugging, - * because PHP DOES NOT generates notice on $row['abc'] if $row === null - * or $row === false (but, if $row is empty array, notice is generated). - */ - public function selectRow(...$args) - { - $total = false; - $rows = $this->_query($args, $total); - if (!is_array($rows)) return $rows; - if (!count($rows)) return array(); - reset($rows); - return current($rows); - } - - /** - * array selectCol(string $query [, $arg1] [,$arg2] ...) - * Return the first column of query result as array. - */ - public function selectCol(...$args) - { - $total = false; - $rows = $this->_query($args, $total); - if (!is_array($rows)) return $rows; - $this->_shrinkLastArrayDimensionCallback($rows); - return $rows; - } - - /** - * scalar selectCell(string $query [, $arg1] [,$arg2] ...) - * Return the first cell of the first column of query result. - * If no one row selected, return null. - */ - public function selectCell(...$args) - { - $total = false; - $rows = $this->_query($args, $total); - if (!is_array($rows)) return $rows; - if (!count($rows)) return null; - reset($rows); - $row = current($rows); - if (!is_array($row)) return $row; - reset($row); - return current($row); - } - - /** - * mixed query(string $query [, $arg1] [,$arg2] ...) - * Alias for select(). May be used for INSERT or UPDATE queries. - */ - public function query(...$args) - { - $total = false; - return $this->_query($args, $total); - } - - /** - * string escape(mixed $s, bool $isIdent=false) - * Enclose the string into database quotes correctly escaping - * special characters. If $isIdent is true, value quoted as identifier - * (e.g.: `value` in MySQL, "value" in Firebird, [value] in MSSQL). - */ - public function escape($s, $isIdent=false) - { - return $this->_performEscape($s, $isIdent); - } - - - /** - * DbSimple_SubQuery subquery(string $query [, $arg1] [,$arg2] ...) - * Выполняет разворачивание плейсхолдеров без коннекта к базе - * Нужно для сложных запросов, состоящих из кусков, которые полезно сохранить - * - */ - public function subquery(...$args) - { - $this->_expandPlaceholders($args,$this->_placeholderNativeArgs !== null); - return new DbSimple_SubQuery($args); - } - - - /** - * callback setLogger(callback $logger) - * Set query logger called before each query is executed. - * Returns previous logger. - */ - public function setLogger($logger) - { - $prev = $this->_logger; - $this->_logger = $logger; - return $prev; - } - - /** - * callback setCacher(callback $cacher) - * Set cache mechanism called during each query if specified. - * Returns previous handler. - */ - public function setCacher($cacher=null) - { - $prev = $this->_cacher; - - if ( is_null($cacher) ) { - return $prev; - } - - if ($cacher instanceof Zend_Cache_Backend_Interface) { - $this->_cacher = $cacher; - return $prev; - } - - if ( is_callable($cacher) ) { - $this->_cacher = new CacherImpl($cacher); - return $prev; - } - - return $prev; - } - - /** - * string setIdentPrefix($prx) - * Set identifier prefix used for $_ placeholder. - */ - public function setIdentPrefix($prx) - { - $old = $this->_identPrefix; - if ($prx !== null) $this->_identPrefix = $prx; - return $old; - } - - /** - * string setCachePrefix($prx) - * Set cache prefix used in key caclulation. - */ - public function setCachePrefix($prx) - { - $old = $this->_cachePrefix; - if ($prx !== null) $this->_cachePrefix = $prx; - return $old; - } - - /** - * Задает имя класса строки - * - * <br>для следующего запроса каждая строка будет - * заменена классом, конструктору которого передается - * массив поле=>значение для этой строки - * - * @param string $name имя класса - * @return DbSimple_Generic_Database указатель на себя - */ - public function setClassName($name) - { - $this->_className = $name; - return $this; - } - - /** - * array getStatistics() - * Returns various statistical information. - */ - public function getStatistics() - { - return $this->_statistics; - } - - - /** - * string _performEscape(mixed $s, bool $isIdent=false) - */ - abstract protected function _performEscape($s, $isIdent=false); - - /** - * object _performNewBlob($id) - * - * Returns new blob object. - */ - abstract protected function _performNewBlob($id=null); - - /** - * list _performGetBlobFieldNames($resultResource) - * Get list of all BLOB field names in result-set. - */ - abstract protected function _performGetBlobFieldNames($result); - - /** - * mixed _performTransformQuery(array &$query, string $how) - * - * Transform query different way specified by $how. - * May return some information about performed transform. - */ - abstract protected function _performTransformQuery(&$queryMain, $how); - - - /** - * resource _performQuery($arrayQuery) - * Must return: - * - For SELECT queries: ID of result-set (PHP resource). - * - For other queries: query status (scalar). - * - For error queries: false (and call _setLastError()). - */ - abstract protected function _performQuery($arrayQuery); - - /** - * mixed _performFetch($resultResource) - * Fetch ONE NEXT row from result-set. - * Must return: - * - For SELECT queries: all the rows of the query (2d arrray). - * - For INSERT queries: ID of inserted row. - * - For UPDATE queries: number of updated rows. - * - For other queries: query status (scalar). - * - For error queries: false (and call _setLastError()). - */ - abstract protected function _performFetch($result); - - /** - * mixed _performTransaction($mode) - * Start new transaction. - */ - abstract protected function _performTransaction($mode=null); - - /** - * mixed _performCommit() - * Commit the transaction. - */ - abstract protected function _performCommit(); - - /** - * mixed _performRollback() - * Rollback the transaction. - */ - abstract protected function _performRollback(); - - /** - * string _performGetPlaceholderIgnoreRe() - * Return regular expression which matches ignored query parts. - * This is needed to skip placeholder replacement inside comments, constants etc. - */ - protected function _performGetPlaceholderIgnoreRe() - { - return ''; - } - - /** - * Returns marker for native database placeholder. E.g. in FireBird it is '?', - * in PostgreSQL - '$1', '$2' etc. - * - * @param int $n Number of native placeholder from the beginning of the query (begins from 0!). - * @return string String representation of native placeholder marker (by default - '?'). - */ - protected function _performGetNativePlaceholderMarker($n) - { - return '?'; - } - - - /** - * array parseDSN(mixed $dsn) - * Parse a data source name. - * See parse_url() for details. - */ - protected function parseDSN($dsn) - { - if (is_array($dsn)) return $dsn; - $parsed = @parse_url($dsn); - if (!$parsed) return null; - $params = null; - if (!empty($parsed['query'])) { - parse_str($parsed['query'], $params); - $parsed += $params; - } - $parsed['dsn'] = $dsn; - return $parsed; - } - - - /** - * array _query($query, &$total) - * See _performQuery(). - */ - private function _query($query, &$total) - { - $this->_resetLastError(); - - // Fetch query attributes. - $this->attributes = $this->_transformQuery($query, 'GET_ATTRIBUTES'); - - // Modify query if needed for total counting. - if ($total) - $this->_transformQuery($query, 'CALC_TOTAL'); - - $rows = false; - $cache_it = false; - // Кешер у нас либо null либо соответствует Zend интерфейсу - if ( !empty($this->attributes['CACHE']) && ($this->_cacher instanceof Zend_Cache_Backend_Interface) ) - { - - $hash = $this->_cachePrefix . md5(serialize($query)); - // Getting data from cache if possible - $fetchTime = $firstFetchTime = 0; - $qStart = microtime(true); - $cacheData = unserialize($this->_cacher->load($hash)); - $queryTime = microtime(true) - $qStart; - - $invalCache = isset($cacheData['invalCache']) ? $cacheData['invalCache'] : null; - $result = isset($cacheData['result']) ? $cacheData['result'] : null; - $rows = isset($cacheData['rows']) ? $cacheData['rows'] : null; - - - $cache_params = $this->attributes['CACHE']; - - // Calculating cache time to live - $re = '/ - (?> - ([0-9]+) #1 - hours - h)? [ \t]* - (?> - ([0-9]+) #2 - minutes - m)? [ \t]* - (?> - ([0-9]+) #3 - seconds - s?)? (,)? - /sx'; - $m = null; - preg_match($re, $cache_params, $m); - $ttl = (isset($m[3])?$m[3]:0) - + (isset($m[2])?$m[2]:0) * 60 - + (isset($m[1])?$m[1]:0) * 3600; - // Cutting out time param - now there are just fields for uniqKey or nothing - $cache_params = trim(preg_replace($re, '', $cache_params, 1)); - - $uniq_key = null; - - // UNIQ_KEY calculation - if (!empty($cache_params)) { - $dummy = null; - // There is no need in query, cos' needle in $this->attributes['CACHE'] - $this->_transformQuery($dummy, 'UNIQ_KEY'); - $uniq_key = call_user_func(array(&$this, 'select'), $dummy); - $uniq_key = md5(serialize($uniq_key)); - } - // Check TTL? - $ok = empty($ttl) || $cacheData; - - // Invalidate cache? - if ($ok && $uniq_key == $invalCache) { - $this->_logQuery($query); - $this->_logQueryStat($queryTime, $fetchTime, $firstFetchTime, $rows); - - } - else $cache_it = true; - } - - if (false === $rows || true === $cache_it) { - $this->_logQuery($query); - - // Run the query (counting time). - $qStart = microtime(true); - $result = $this->_performQuery($query); - $fetchTime = $firstFetchTime = 0; - - if (is_resource($result) || is_object($result)) { - $rows = array(); - // Fetch result row by row. - $fStart = microtime(true); - $row = $this->_performFetch($result); - $firstFetchTime = microtime(true) - $fStart; - if (!empty($row)) { - $rows[] = $row; - while ($row=$this->_performFetch($result)) { - $rows[] = $row; - } - } - $fetchTime = microtime(true) - $fStart; - } else { - $rows = $result; - } - $queryTime = microtime(true) - $qStart; - - // Log query statistics. - $this->_logQueryStat($queryTime, $fetchTime, $firstFetchTime, $rows); - - // Prepare BLOB objects if needed. - if (is_array($rows) && !empty($this->attributes['BLOB_OBJ'])) { - $blobFieldNames = $this->_performGetBlobFieldNames($result); - foreach ($blobFieldNames as $name) { - for ($r = count($rows)-1; $r>=0; $r--) { - $rows[$r][$name] =& $this->_performNewBlob($rows[$r][$name]); - } - } - } - - // Transform resulting rows. - $result = $this->_transformResult($rows); - - // Storing data in cache - if ($cache_it && $this->_cacher) - { - $this->_cacher->save( - serialize(array( - 'invalCache' => $uniq_key, - 'result' => $result, - 'rows' => $rows - )), - $hash, - array(), - $ttl==0?false:$ttl - ); - } - - } - // Count total number of rows if needed. - if (is_array($result) && $total) { - $this->_transformQuery($query, 'GET_TOTAL'); - $total = call_user_func_array(array(&$this, 'selectCell'), $query); - } - - if ($this->_className) - { - foreach($result as $k=>$v) - $result[$k] = new $this->_className($v); - $this->_className = ''; - } - - return $result; - } - - - /** - * mixed _transformQuery(array &$query, string $how) - * - * Transform query different way specified by $how. - * May return some information about performed transform. - */ - private function _transformQuery(&$query, $how) - { - // Do overriden transformation. - $result = $this->_performTransformQuery($query, $how); - if ($result === true) return $result; - // Common transformations. - switch ($how) { - case 'GET_ATTRIBUTES': - // Extract query attributes. - $options = array(); - $q = $query[0]; - $m = null; - while (preg_match('/^ \s* -- [ \t]+ (\w+): ([^\r\n]+) [\r\n]* /sx', $q, $m)) { - $options[$m[1]] = trim($m[2]); - $q = substr($q, strlen($m[0])); - } - return $options; - case 'UNIQ_KEY': - $q = $this->attributes['CACHE']; - $query = array(); - while(preg_match('/(\w+)\.\w+/sx', $q, $m)) { - $query[] = 'SELECT MAX('.$m[0].') AS M, COUNT(*) AS C FROM '.$m[1]; - $q = substr($q, strlen($m[0])); - } - $query = " -- UNIQ_KEY\n". - join("\nUNION\n", $query); - return true; - } - // No such transform. - $this->_setLastError(-1, "No such transform type: $how", $query); - } - - - /** - * void _expandPlaceholders(array &$queryAndArgs, bool $useNative=false) - * Replace placeholders by quoted values. - * Modify $queryAndArgs. - */ - protected function _expandPlaceholders(&$queryAndArgs, $useNative=false) - { - $cacheCode = null; - if ($this->_logger) { - // Serialize is much faster than placeholder expansion. So use caching. - $cacheCode = md5(serialize($queryAndArgs) . '|' . $useNative . '|' . $this->_identPrefix); - if (isset($this->_placeholderCache[$cacheCode])) { - $queryAndArgs = $this->_placeholderCache[$cacheCode]; - return; - } - } - - if (!is_array($queryAndArgs)) { - $queryAndArgs = array($queryAndArgs); - } - - $this->_placeholderNativeArgs = $useNative? array() : null; - $this->_placeholderArgs = array_reverse($queryAndArgs); - - $query = array_pop($this->_placeholderArgs); // array_pop is faster than array_shift - - // Do all the work. - $this->_placeholderNoValueFound = false; - $query = $this->_expandPlaceholdersFlow($query); - - if ($useNative) { - array_unshift($this->_placeholderNativeArgs, $query); - $queryAndArgs = $this->_placeholderNativeArgs; - } else { - $queryAndArgs = array($query); - } - - if ($cacheCode) { - $this->_placeholderCache[$cacheCode] = $queryAndArgs; - } - } - - - /** - * Do real placeholder processing. - * Imply that all interval variables (_placeholder_*) already prepared. - * May be called recurrent! - */ - private function _expandPlaceholdersFlow($query) - { - $re = '{ - (?> - # Ignored chunks. - (?> - # Comment. - -- [^\r\n]* - ) - | - (?> - # DB-specifics. - ' . trim($this->_performGetPlaceholderIgnoreRe()) . ' - ) - ) - | - (?> - # Optional blocks - \{ - # Use "+" here, not "*"! Else nested blocks are not processed well. - ( (?> (?>(\??)[^{}]+) | (?R) )* ) #1 - \} - ) - | - (?> - # Placeholder - (\?) ( [_dsafn&|\#]? ) #2 #3 - ) - }sx'; - $query = preg_replace_callback( - $re, - array(&$this, '_expandPlaceholdersCallback'), - $query - ); - return $query; - } - - static $join = array( - '|' => array('inner' => ' AND ', 'outer' => ') OR (',), - '&' => array('inner' => ' OR ', 'outer' => ') AND (',), - 'a' => array('inner' => ', ', 'outer' => '), (',), - ); - - /** - * string _expandPlaceholdersCallback(list $m) - * Internal function to replace placeholders (see preg_replace_callback). - */ - private function _expandPlaceholdersCallback($m) - { - // Placeholder. - if (!empty($m[3])) { - $type = $m[4]; - - // Idenifier prefix. - if ($type == '_') { - return $this->_identPrefix; - } - - // Value-based placeholder. - if (!$this->_placeholderArgs) return 'DBSIMPLE_ERROR_NO_VALUE'; - $value = array_pop($this->_placeholderArgs); - - // Skip this value? - if ($value === DBSIMPLE_SKIP) { - $this->_placeholderNoValueFound = true; - return ''; - } - - // First process guaranteed non-native placeholders. - switch ($type) { - case 's': - if (!($value instanceof DbSimple_SubQuery)) - return 'DBSIMPLE_ERROR_VALUE_NOT_SUBQUERY'; - return $value->get($this->_placeholderNativeArgs); - case '|': - case '&': - case 'a': - if (!$value) $this->_placeholderNoValueFound = true; - if (!is_array($value)) return 'DBSIMPLE_ERROR_VALUE_NOT_ARRAY'; - $parts = array(); - $multi = array(); //массив для двойной вложенности - $mult = $type!='a' || is_int(key($value)) && is_array(current($value)); - foreach ($value as $prefix => $field) { - //превращаем $value в двумерный нуменованный массив - if (!is_array($field)) { - $field = array($prefix => $field); - $prefix = 0; - } - $prefix = is_int($prefix) ? '' : - $this->escape($this->_addPrefix2Table($prefix), true) . '.'; - //для мультиинсерта очищаем ключи - их быть не может по синтаксису - if ($mult && $type=='a') - $field = array_values($field); - foreach ($field as $k => $v) - { - if ($v instanceof DbSimple_SubQuery) - $v = $v->get($this->_placeholderNativeArgs); - else - $v = $v === null? 'NULL' : $this->escape($v); - if (!is_int($k)) { - $k = $this->escape($k, true); - $parts[] = "$prefix$k=$v"; - } else { - $parts[] = $v; - } - } - if ($mult) - { - $multi[] = join(self::$join[$type]['inner'], $parts); - $parts = array(); - } - } - return $mult ? join(self::$join[$type]['outer'], $multi) : join(', ', $parts); - case '#': - // Identifier. - if (!is_array($value)) - { - if ($value instanceof DbSimple_SubQuery) - return $value->get($this->_placeholderNativeArgs); - return $this->escape($this->_addPrefix2Table($value), true); - } - $parts = array(); - foreach ($value as $table => $identifiers) - { - if (!is_array($identifiers)) - $identifiers = array($identifiers); - $prefix = ''; - if (!is_int($table)) - $prefix = $this->escape($this->_addPrefix2Table($table), true) . '.'; - foreach ($identifiers as $identifier) - if ($identifier instanceof DbSimple_SubQuery) - $parts[] = $identifier->get($this->_placeholderNativeArgs); - elseif (!is_string($identifier)) - return 'DBSIMPLE_ERROR_ARRAY_VALUE_NOT_STRING'; - else - $parts[] = $prefix . ($identifier=='*' ? '*' : - $this->escape($this->_addPrefix2Table($identifier), true)); - } - return join(', ', $parts); - case 'n': - // NULL-based placeholder. - return empty($value)? 'NULL' : intval($value); - } - - // Native arguments are not processed. - if ($this->_placeholderNativeArgs !== null) { - $this->_placeholderNativeArgs[] = $value; - return $this->_performGetNativePlaceholderMarker(count($this->_placeholderNativeArgs) - 1); - } - - // In non-native mode arguments are quoted. - if ($value === null) return 'NULL'; - switch ($type) { - case '': - if (!is_scalar($value)) return 'DBSIMPLE_ERROR_VALUE_NOT_SCALAR'; - return $this->escape($value); - case 'd': - return intval($value); - case 'f': - return str_replace(',', '.', floatval($value)); - } - // By default - escape as string. - return $this->escape($value); - } - - // Optional block. - if (isset($m[1]) && strlen($block=$m[1])) - { - $prev = $this->_placeholderNoValueFound; - if ($this->_placeholderNativeArgs !== null) - $prevPh = $this->_placeholderNativeArgs; - - // Проверка на {? } - условный блок - $skip = false; - if ($m[2]=='?') - { - $skip = array_pop($this->_placeholderArgs) === DBSIMPLE_SKIP; - $block[0] = ' '; - } - - $block = $this->_expandOptionalBlock($block); - - if ($skip) - $block = ''; - - if ($this->_placeholderNativeArgs !== null) - if ($this->_placeholderNoValueFound) - $this->_placeholderNativeArgs = $prevPh; - $this->_placeholderNoValueFound = $prev; // recurrent-safe - return $block; - } - - // Default: skipped part of the string. - return $m[0]; - } - - - /** - * Заменяет ?_ на текущий префикс - * - * @param string $table имя таблицы - * @return string имя таблицы - */ - private function _addPrefix2Table($table) - { - if (substr($table, 0, 2) == '?_') - $table = $this->_identPrefix . substr($table, 2); - return $table; - } - - - /** - * Разбирает опциональный блок - условие | - * - * @param string $block блок, который нужно разобрать - * @return string что получается в результате разбора блока - */ - private function _expandOptionalBlock($block) - { - $alts = array(); - $alt = ''; - $sub=0; - $exp = explode('|',$block); - // Оптимизация, так как в большинстве случаев | не используется - if (count($exp)==1) - $alts=$exp; - else - foreach ($exp as $v) - { - // Реализуем автоматный магазин для нахождения нужной скобки - // На суммарную парность скобок проверять нет необходимости - об этом заботится регулярка - $sub+=substr_count($v,'{'); - $sub-=substr_count($v,'}'); - if ($sub>0) - $alt.=$v.'|'; - else - { - $alts[]=$alt.$v; - $alt=''; - } - } - $r=''; - foreach ($alts as $block) - { - $this->_placeholderNoValueFound = false; - $block = $this->_expandPlaceholdersFlow($block); - // Необходимо пройти все блоки, так как если пропустить оставшиесь, - // то это нарушит порядок подставляемых значений - if ($this->_placeholderNoValueFound == false && $r=='') - $r = ' '.$block.' '; - } - return $r; - } - - - /** - * void _setLastError($code, $msg, $query) - * Set last database error context. - * Aditionally expand placeholders. - */ - protected function _setLastError($code, $msg, $query) - { - if (is_array($query)) { - $this->_expandPlaceholders($query, false); - $query = $query[0]; - } - return parent::_setLastError($code, $msg, $query); - } - - - /** - * Convert SQL field-list to COUNT(...) clause - * (e.g. 'DISTINCT a AS aa, b AS bb' -> 'COUNT(DISTINCT a, b)'). - */ - private function _fieldList2Count($fields) - { - $m = null; - if (preg_match('/^\s* DISTINCT \s* (.*)/sx', $fields, $m)) { - $fields = $m[1]; - $fields = preg_replace('/\s+ AS \s+ .*? (?=,|$)/sx', '', $fields); - return "COUNT(DISTINCT $fields)"; - } else { - return 'COUNT(*)'; - } - } - - - /** - * array _transformResult(list $rows) - * Transform resulting rows to various formats. - */ - private function _transformResult($rows) - { - // is not array - if (!is_array($rows) || !$rows) - return $rows; - - // Find ARRAY_KEY* AND PARENT_KEY fields in field list. - $pk = null; - $ak = array(); - foreach (array_keys(current($rows)) as $fieldName) - if (0 == strncasecmp($fieldName, DBSIMPLE_ARRAY_KEY, strlen(DBSIMPLE_ARRAY_KEY))) - $ak[] = $fieldName; - elseif (0 == strncasecmp($fieldName, DBSIMPLE_PARENT_KEY, strlen(DBSIMPLE_PARENT_KEY))) - $pk = $fieldName; - - if (!$ak) - return $rows; - - natsort($ak); // sort ARRAY_KEY* using natural comparision - // Tree-based array? Fields: ARRAY_KEY, PARENT_KEY - if ($pk !== null) - return $this->_transformResultToForest($rows, $ak[0], $pk); - // Key-based array? Fields: ARRAY_KEY. - return $this->_transformResultToHash($rows, $ak); - } - - - /** - * Converts rowset to key-based array. - * - * @param array $rows Two-dimensional array of resulting rows. - * @param array $ak List of ARRAY_KEY* field names. - * @return array Transformed array. - */ - private function _transformResultToHash(array $rows, array $arrayKeys) - { - $result = array(); - foreach ($rows as $row) { - // Iterate over all of ARRAY_KEY* fields and build array dimensions. - $current =& $result; - foreach ($arrayKeys as $ak) { - $key = $row[$ak]; - unset($row[$ak]); // remove ARRAY_KEY* field from result row - if ($key !== null) { - $current =& $current[$key]; - } else { - // IF ARRAY_KEY field === null, use array auto-indices. - $tmp = array(); - $current[] =& $tmp; - $current =& $tmp; - unset($tmp); // we use $tmp, because don't know the value of auto-index - } - } - $current = $row; // save the row in last dimension - } - return $result; - } - - - /** - * Converts rowset to the forest. - * - * @param array $rows Two-dimensional array of resulting rows. - * @param string $idName Name of ID field. - * @param string $pidName Name of PARENT_ID field. - * @return array Transformed array (tree). - */ - private function _transformResultToForest(array $rows, $idName, $pidName) - { - $children = array(); // children of each ID - $ids = array(); - // Collect who are children of whom. - foreach ($rows as $i=>$r) { - $row =& $rows[$i]; - $id = $row[$idName]; - if ($id === null) { - // Rows without an ID are totally invalid and makes the result tree to - // be empty (because PARENT_ID = null means "a root of the tree"). So - // skip them totally. - continue; - } - $pid = $row[$pidName]; - if ($id == $pid) $pid = null; - $children[$pid][$id] =& $row; - if (!isset($children[$id])) $children[$id] = array(); - $row['childNodes'] =& $children[$id]; - $ids[$id] = true; - } - // Root elements are elements with non-found PIDs. - $forest = array(); - foreach ($rows as $i=>$r) { - $row =& $rows[$i]; - $id = $row[$idName]; - $pid = $row[$pidName]; - if ($pid == $id) $pid = null; - if (!isset($ids[$pid])) { - $forest[$row[$idName]] =& $row; - } - unset($row[$idName]); - unset($row[$pidName]); - } - return $forest; - } - - - /** - * Replaces the last array in a multi-dimensional array $V by its first value. - * Used for selectCol(), when we need to transform (N+1)d resulting array - * to Nd array (column). - */ - private function _shrinkLastArrayDimensionCallback(&$v) - { - if (!$v) return; - reset($v); - if (!is_array($firstCell = current($v))) { - $v = $firstCell; - } else { - array_walk($v, array(&$this, '_shrinkLastArrayDimensionCallback')); - } - } - - - /** - * void _logQuery($query, $noTrace=false) - * Must be called on each query. - * If $noTrace is true, library caller is not solved (speed improvement). - */ - protected function _logQuery($query, $noTrace=false) - { - if (!$this->_logger) return; - $this->_expandPlaceholders($query, false); - $args = array(); - $args[] =& $this; - $args[] = $query[0]; - $args[] = $noTrace? null : $this->findLibraryCaller(); - return call_user_func_array($this->_logger, $args); - } - - - /** - * void _logQueryStat($queryTime, $fetchTime, $firstFetchTime, $rows) - * Log information about performed query statistics. - */ - private function _logQueryStat($queryTime, $fetchTime, $firstFetchTime, $rows) - { - // Always increment counters. - $this->_statistics['time'] += $queryTime; - $this->_statistics['count']++; - - // If no logger, economize CPU resources and actually log nothing. - if (!$this->_logger) return; - - $dt = round($queryTime * 1000); - $firstFetchTime = round($firstFetchTime*1000); - $tailFetchTime = round($fetchTime * 1000) - $firstFetchTime; - $log = " -- "; - if ($firstFetchTime + $tailFetchTime) { - $log = sprintf(" -- %d ms = %d+%d".($tailFetchTime? "+%d" : ""), $dt, $dt-$firstFetchTime-$tailFetchTime, $firstFetchTime, $tailFetchTime); - } else { - $log = sprintf(" -- %d ms", $dt); - } - $log .= "; returned "; - - if (!is_array($rows)) { - $log .= $this->escape($rows); - } else { - $detailed = null; - if (count($rows) == 1) { - $len = 0; - $values = array(); - foreach ($rows[0] as $k=>$v) { - $len += strlen($v ?? ''); - if ($len > $this->MAX_LOG_ROW_LEN) { - break; - } - $values[] = $v === null? 'NULL' : $this->escape($v); - } - if ($len <= $this->MAX_LOG_ROW_LEN) { - $detailed = "(" . preg_replace("/\r?\n/", "\\n", join(', ', $values)) . ")"; - } - } - if ($detailed) { - $log .= $detailed; - } else { - $log .= count($rows). " row(s)"; - } - } - - $this->_logQuery($log, true); - } - - - // Identifiers prefix (used for ?_ placeholder). - private $_identPrefix = ''; - - // Queries statistics. - private $_statistics = array( - 'time' => 0, - 'count' => 0, - ); - - private $_cachePrefix = ''; - private $_className = ''; - - private $_logger = null; - private $_cacher = null; - private $_placeholderArgs, $_placeholderNativeArgs, $_placeholderCache=array(); - private $_placeholderNoValueFound; - - /** - * When string representation of row (in characters) is greater than this, - * row data will not be logged. - */ - private $MAX_LOG_ROW_LEN = 128; -} - - -/** - * Database BLOB. - * Can read blob chunk by chunk, write data to BLOB. - */ -interface DbSimple_Blob -{ - /** - * string read(int $length) - * Returns following $length bytes from the blob. - */ - public function read($len); - - /** - * string write($data) - * Appends data to blob. - */ - public function write($data); - - /** - * int length() - * Returns length of the blob. - */ - public function length(); - - /** - * blobid close() - * Closes the blob. Return its ID. No other way to obtain this ID! - */ - public function close(); -} - - -/** - * Класс для хранения подзапроса - результата выполнения функции - * DbSimple_Generic_Database::subquery - * - */ -class DbSimple_SubQuery -{ - private $query=array(); - - public function __construct(array $q) - { - $this->query = $q; - } - - /** - * Возвращает сам запрос и добавляет плейсхолдеры в массив переданный по ссылке - * - * @param &array|null - ссылка на массив плейсхолдеров - * @return string - */ - public function get(&$ph) - { - if ($ph !== null) - $ph = array_merge($ph, array_slice($this->query,1,null,true)); - return $this->query[0]; - } -} - - -/** - * Support for error tracking. - * Can hold error messages, error queries and build proper stacktraces. - */ -abstract class DbSimple_LastError -{ - public $error = null; - public $errmsg = null; - private $errorHandler = null; - private $ignoresInTraceRe = 'DbSimple_.*::.* | call_user_func.*'; - - /** - * abstract void _logQuery($query) - * Must be overriden in derived class. - */ - abstract protected function _logQuery($query); - - /** - * void _resetLastError() - * Reset the last error. Must be called on correct queries. - */ - protected function _resetLastError() - { - $this->error = $this->errmsg = null; - } - - /** - * void _setLastError(int $code, string $message, string $query) - * Fill $this->error property with error information. Error context - * (code initiated the query outside DbSimple) is assigned automatically. - */ - protected function _setLastError($code, $msg, $query) - { - $context = "unknown"; - if ($t = $this->findLibraryCaller()) { - $context = (isset($t['file'])? $t['file'] : '?') . ' line ' . (isset($t['line'])? $t['line'] : '?'); - } - $this->error = array( - 'code' => $code, - 'message' => rtrim($msg), - 'query' => $query, - 'context' => $context, - ); - $this->errmsg = rtrim($msg) . ($context? " at $context" : ""); - - $this->_logQuery(" -- error #".$code.": ".preg_replace('/(\r?\n)+/s', ' ', $this->errmsg)); - - if (is_callable($this->errorHandler)) { - call_user_func($this->errorHandler, $this->errmsg, $this->error); - } - - return false; - } - - - /** - * callback setErrorHandler(callback $handler) - * Set new error handler called on database errors. - * Handler gets 3 arguments: - * - error message - * - full error context information (last query etc.) - */ - public function setErrorHandler($handler) - { - $prev = $this->errorHandler; - $this->errorHandler = $handler; - // In case of setting first error handler for already existed - // error - call the handler now (usual after connect()). - if (!$prev && $this->error && $this->errorHandler) { - call_user_func($this->errorHandler, $this->errmsg, $this->error); - } - return $prev; - } - - /** - * void addIgnoreInTrace($reName) - * Add regular expression matching ClassName::functionName or functionName. - * Matched stack frames will be ignored in stack traces passed to query logger. - */ - public function addIgnoreInTrace($name) - { - $this->ignoresInTraceRe .= "|" . $name; - } - - /** - * array of array findLibraryCaller() - * Return part of stacktrace before calling first library method. - * Used in debug purposes (query logging etc.). - */ - public function findLibraryCaller() - { - $caller = call_user_func( - array(&$this, 'debug_backtrace_smart'), - $this->ignoresInTraceRe, - true - ); - return $caller; - } - - /** - * array debug_backtrace_smart($ignoresRe=null, $returnCaller=false) - * - * Return stacktrace. Correctly work with call_user_func* - * (totally skip them correcting caller references). - * If $returnCaller is true, return only first matched caller, - * not all stacktrace. - * - * @version 2.03 - */ - private function debug_backtrace_smart($ignoresRe=null, $returnCaller=false) - { - $trace = debug_backtrace(); - - if ($ignoresRe !== null) - $ignoresRe = "/^(?>{$ignoresRe})$/six"; - $smart = array(); - $framesSeen = 0; - for ($i=0, $n=count($trace); $i<$n; $i++) { - $t = $trace[$i]; - if (!$t) continue; - - // Next frame. - $next = isset($trace[$i+1])? $trace[$i+1] : null; - - // Dummy frame before call_user_func* frames. - if (!isset($t['file'])) { - $t['over_function'] = $trace[$i+1]['function']; - $t = $t + $trace[$i+1]; - $trace[$i+1] = null; // skip call_user_func on next iteration - $next = isset($trace[$i+2])? $trace[$i+2] : null; // Correct Next frame. - } - - // Skip myself frame. - if (++$framesSeen < 2) continue; - - // 'class' and 'function' field of next frame define where - // this frame function situated. Skip frames for functions - // situated in ignored places. - if ($ignoresRe && $next) { - // Name of function "inside which" frame was generated. - $frameCaller = (isset($next['class'])? $next['class'].'::' : '') . (isset($next['function'])? $next['function'] : ''); - if (preg_match($ignoresRe, $frameCaller)) continue; - } - - // On each iteration we consider ability to add PREVIOUS frame - // to $smart stack. - if ($returnCaller) return $t; - $smart[] = $t; - } - return $smart; - } - -} diff --git a/includes/libs/DbSimple/Generic.php b/includes/libs/DbSimple/Generic.php deleted file mode 100644 index 5dc2f144..00000000 --- a/includes/libs/DbSimple/Generic.php +++ /dev/null @@ -1,193 +0,0 @@ -<?php -/** - * DbSimple_Generic: universal database connected by DSN. - * (C) Dk Lab, http://en.dklab.ru - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * See http://www.gnu.org/copyleft/lesser.html - * - * Use static DbSimple_Generic::connect($dsn) call if you don't know - * database type and parameters, but have its DSN. - * - * Additional keys can be added by appending a URI query string to the - * end of the DSN. - * - * The format of the supplied DSN is in its fullest form: - * phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true - * - * Most variations are allowed: - * phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644 - * phptype://username:password@hostspec/database_name - * phptype://username:password@hostspec - * phptype://username@hostspec - * phptype://hostspec/database - * phptype://hostspec - * phptype(dbsyntax) - * phptype - * - * Parsing code is partially grabbed from PEAR DB class, - * initial author: Tomas V.V.Cox <cox@idecnet.com>. - * - * Contains 3 classes: - * - DbSimple_Generic: database factory class - * - DbSimple_Generic_Database: common database methods - * - DbSimple_Generic_Blob: common BLOB support - * - DbSimple_Generic_LastError: error reporting and tracking - * - * Special result-set fields: - * - ARRAY_KEY* ("*" means "anything") - * - PARENT_KEY - * - * Transforms: - * - GET_ATTRIBUTES - * - CALC_TOTAL - * - GET_TOTAL - * - UNIQ_KEY - * - * Query attributes: - * - BLOB_OBJ - * - CACHE - * - * @author Dmitry Koterov, http://forum.dklab.ru/users/DmitryKoterov/ - * @author Konstantin Zhinko, http://forum.dklab.ru/users/KonstantinGinkoTit/ - * - * @version 2.x $Id$ - */ - -/** - * Use this constant as placeholder value to skip optional SQL block [...]. - */ -if (!defined('DBSIMPLE_SKIP')) - define('DBSIMPLE_SKIP', log(0)); - -/** - * Names of special columns in result-set which is used - * as array key (or karent key in forest-based resultsets) in - * resulting hash. - */ -if (!defined('DBSIMPLE_ARRAY_KEY')) - define('DBSIMPLE_ARRAY_KEY', 'ARRAY_KEY'); // hash-based resultset support -if (!defined('DBSIMPLE_PARENT_KEY')) - define('DBSIMPLE_PARENT_KEY', 'PARENT_KEY'); // forrest-based resultset support - - -/** - * DbSimple factory. - */ -class DbSimple_Generic -{ - /** - * DbSimple_Generic connect(mixed $dsn) - * - * Universal static function to connect ANY database using DSN syntax. - * Choose database driver according to DSN. Return new instance - * of this driver. - * - * You can connect to MySQL by socket using this new syntax (like PDO DSN): - * $dsn = 'mysqli:unix_socket=/cloudsql/app:instance;user=root;pass=;dbname=testdb'; - * $dsn = 'mypdo:unix_socket=/cloudsql/app:instance;charset=utf8;user=testuser;pass=mypassword;dbname=testdb'; - * - * Connection by host also can be made with this syntax. - * Or you can use old syntax: - * $dsn = 'mysql://testuser:mypassword@127.0.0.1/testdb'; - * - */ - public static function connect($dsn) - { - // Load database driver and create its instance. - $parsed = DbSimple_Generic::parseDSN($dsn); - if (!$parsed) { - $dummy = null; - return $dummy; - } - $class = 'DbSimple_'.ucfirst($parsed['scheme']); - if (!class_exists($class)) { - $file = __DIR__.'/'.ucfirst($parsed['scheme']). ".php"; - if (is_file($file)) { - require_once($file); - } else { - trigger_error("Error loading database driver: no file $file", E_USER_ERROR); - return null; - } - } - $object = new $class($parsed); - if (isset($parsed['ident_prefix'])) { - $object->setIdentPrefix($parsed['ident_prefix']); - } - $object->setCachePrefix(md5(serialize($parsed['dsn']))); - return $object; - } - - - /** - * array parseDSN(mixed $dsn) - * Parse a data source name. - * See parse_url() for details. - */ - public static function parseDSN($dsn) - { - if (is_array($dsn)) return $dsn; - $parsed = parse_url($dsn); - if (!$parsed) return null; - - $params = null; - if (!empty($parsed['query'])) { - parse_str($parsed['query'], $params); - $parsed += $params; - } - - if ( empty($parsed['host']) && empty($parsed['socket']) ) { - // Parse as DBO DSN string - $parsedPdo = self::parseDsnPdo($parsed['path']); - unset($parsed['path']); - $parsed = array_merge($parsed, $parsedPdo); - } - - $parsed['dsn'] = $dsn; - return $parsed; - } // parseDSN - - - /** - * Parse string as DBO DSN string. - * - * @param $str - * @return array - */ - public static function parseDsnPdo($str) { - - if (substr($str, 0, strlen('mysql:')) == 'mysql:') { - $str = substr($str, strlen('mysql:')); - } - - $arr = explode(';', $str); - - $result = array(); - foreach ($arr as $k=>$v) { - $v = explode('=', $v); - if (count($v) == 2) - $result[ $v[0] ] = $v[1]; - } - - if ( isset($result['unix_socket']) ) { - $result['socket'] = $result['unix_socket']; - unset($result['unix_socket']); - } - - if ( isset($result['dbname']) ) { - $result['path'] = $result['dbname']; - unset($result['dbname']); - } - - if ( isset($result['charset']) ) { - $result['enc'] = $result['charset']; - unset($result['charset']); - } - - return $result; - } // parseDsnPdo - -} // DbSimple_Generic class diff --git a/includes/libs/DbSimple/Mysqli.php b/includes/libs/DbSimple/Mysqli.php deleted file mode 100644 index 2c1fcccd..00000000 --- a/includes/libs/DbSimple/Mysqli.php +++ /dev/null @@ -1,245 +0,0 @@ -<?php -/** - * DbSimple_Mysql: MySQL database. - * (C) Dk Lab, http://en.dklab.ru - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * See http://www.gnu.org/copyleft/lesser.html - * - * Placeholders end blobs are emulated. - * - * @author Dmitry Koterov, http://forum.dklab.ru/users/DmitryKoterov/ - * @author Konstantin Zhinko, http://forum.dklab.ru/users/KonstantinGinkoTit/ - * - * @version 2.x $Id: Mysqli.php 247 2008-08-18 21:17:08Z dk $ - */ -require_once __DIR__.'/Database.php'; - - -/** - * Database class for MySQL. - */ -class DbSimple_Mysqli extends DbSimple_Database -{ - var $link; - - private $_lastQuery; - - /** - * constructor(string $dsn) - * Connect to MySQL server. - */ - function __construct($dsn) - { - - if (!is_callable("mysqli_connect")) - return $this->_setLastError("-1", "MySQLi extension is not loaded", "mysqli_connect"); - - if (!empty($dsn["persist"])) { - if (version_compare(PHP_VERSION, '5.3') < 0) { - return $this->_setLastError("-1", "Persistent connections in MySQLi is allowable since PHP 5.3", "mysqli_connect"); - } else { - $dsn["host"] = "p:".$dsn["host"]; - } - } - - if ( isset($dsn['socket']) ) { - // Socket connection - $this->link = mysqli_connect( - null // host - ,empty($dsn['user']) ? 'root' : $dsn['user'] // user - ,empty($dsn['pass']) ? '' : $dsn['pass'] // password - ,preg_replace('{^/}s', '', $dsn['path']) // schema - ,null // port - ,$dsn['socket'] // socket - ); - } else if (isset($dsn['host']) ) { - // Host connection - $this->link = mysqli_connect( - $dsn['host'] - ,empty($dsn['user']) ? 'root' : $dsn['user'] - ,empty($dsn['pass']) ? '' : $dsn['pass'] - ,preg_replace('{^/}s', '', $dsn['path']) - ,empty($dsn['port']) ? null : $dsn['port'] - ); - } else { - return $this->_setDbError('mysqli_connect()'); - } - $this->_resetLastError(); - if (!$this->link) return $this->_setDbError('mysqli_connect()'); - - mysqli_set_charset($this->link, isset($dsn['enc']) ? $dsn['enc'] : 'UTF8'); - } - - - protected function _performEscape($s, $isIdent=false) - { - if (!$isIdent) - return "'" . mysqli_real_escape_string($this->link, $s) . "'"; - else - return "`" . str_replace('`', '``', $s) . "`"; - } - - - protected function _performNewBlob($blobid=null) - { - return new DbSimple_Mysqli_Blob($this, $blobid); - } - - - protected function _performGetBlobFieldNames($result) - { - $allFields = mysqli_fetch_fields($result); - $blobFields = array(); - - if (!empty($allFields)) - { - foreach ($allFields as $field) - if (stripos($field["type"], "BLOB") !== false) - $blobFields[] = $field["name"]; - } - return $blobFields; - } - - - protected function _performGetPlaceholderIgnoreRe() - { - return ' - " (?> [^"\\\\]+|\\\\"|\\\\)* " | - \' (?> [^\'\\\\]+|\\\\\'|\\\\)* \' | - ` (?> [^`]+ | ``)* ` | # backticks - /\* .*? \*/ # comments - '; - } - - - protected function _performTransaction($parameters=null) - { - return mysqli_begin_transaction($this->link); - } - - - protected function _performCommit() - { - return mysqli_commit($this->link); - } - - - protected function _performRollback() - { - return mysqli_rollback($this->link); - } - - - protected function _performTransformQuery(&$queryMain, $how) - { - // If we also need to calculate total number of found rows... - switch ($how) - { - // Prepare total calculation (if possible) - case 'CALC_TOTAL': - $m = null; - if (preg_match('/^(\s* SELECT)(.*)/six', $queryMain[0], $m)) - $queryMain[0] = $m[1] . ' SQL_CALC_FOUND_ROWS' . $m[2]; - return true; - - // Perform total calculation. - case 'GET_TOTAL': - // Built-in calculation available? - $queryMain = array('SELECT FOUND_ROWS()'); - return true; - } - - return false; - } - - - protected function _performQuery($queryMain) - { - $this->_lastQuery = $queryMain; - $this->_expandPlaceholders($queryMain, false); - mysqli_ping($this->link); - $result = mysqli_query($this->link, $queryMain[0]); - if ($result === false) - return $this->_setDbError($queryMain[0]); - - if ($this->link->warning_count) { - if ($warn = $this->link->query("SHOW WARNINGS")) { - while ($warnRow = $warn->fetch_row()) - if ($warnRow[0] === 'Warning') - $this->_setLastError(-$warnRow[1], $warnRow[2], $queryMain[0]); - - $warn->close(); - } - } - - if (!is_object($result)) { - if (preg_match('/^\s* INSERT \s+/six', $queryMain[0])) - { - // INSERT queries return generated ID. - return mysqli_insert_id($this->link); - } - // Non-SELECT queries return number of affected rows, SELECT - resource. - return mysqli_affected_rows($this->link); - } - return $result; - } - - - protected function _performFetch($result) - { - $row = mysqli_fetch_assoc($result); - if (mysqli_error($this->link)) return $this->_setDbError($this->_lastQuery); - if ($row === false) return null; - return $row; - } - - - protected function _setDbError($query) - { - if ($this->link) { - return $this->_setLastError(mysqli_errno($this->link), mysqli_error($this->link), $query); - } else { - return $this->_setLastError(mysqli_connect_errno(), mysqli_connect_error(), $query); - } - } -} - - -class DbSimple_Mysqli_Blob implements DbSimple_Blob -{ - // MySQL does not support separate BLOB fetching. - private $blobdata = null; - private $curSeek = 0; - - public function __construct(&$database, $blobdata=null) - { - $this->blobdata = $blobdata; - $this->curSeek = 0; - } - - public function read($len) - { - $p = $this->curSeek; - $this->curSeek = min($this->curSeek + $len, strlen($this->blobdata)); - return substr($this->blobdata, $p, $len); - } - - public function write($data) - { - $this->blobdata .= $data; - } - - public function close() - { - return $this->blobdata; - } - - public function length() - { - return strlen($this->blobdata); - } -} diff --git a/includes/libs/DbSimple/Zend/Cache.php b/includes/libs/DbSimple/Zend/Cache.php deleted file mode 100644 index aff2e653..00000000 --- a/includes/libs/DbSimple/Zend/Cache.php +++ /dev/null @@ -1,250 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Cache - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id: Cache.php 24656 2012-02-26 06:02:53Z adamlundrigan $ - */ - - -/** - * @package Zend_Cache - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -abstract class Zend_Cache -{ - - /** - * Standard frontends - * - * @var array - */ - public static $standardFrontends = array('Core', 'Output', 'Class', 'File', 'Function', 'Page'); - - /** - * Standard backends - * - * @var array - */ - public static $standardBackends = array('File', 'Sqlite', 'Memcached', 'Libmemcached', 'Apc', 'ZendPlatform', - 'Xcache', 'TwoLevels', 'WinCache', 'ZendServer_Disk', 'ZendServer_ShMem'); - - /** - * Standard backends which implement the ExtendedInterface - * - * @var array - */ - public static $standardExtendedBackends = array('File', 'Apc', 'TwoLevels', 'Memcached', 'Libmemcached', 'Sqlite', 'WinCache'); - - /** - * Only for backward compatibility (may be removed in next major release) - * - * @var array - * @deprecated - */ - public static $availableFrontends = array('Core', 'Output', 'Class', 'File', 'Function', 'Page'); - - /** - * Only for backward compatibility (may be removed in next major release) - * - * @var array - * @deprecated - */ - public static $availableBackends = array('File', 'Sqlite', 'Memcached', 'Libmemcached', 'Apc', 'ZendPlatform', 'Xcache', 'WinCache', 'TwoLevels'); - - /** - * Consts for clean() method - */ - const CLEANING_MODE_ALL = 'all'; - const CLEANING_MODE_OLD = 'old'; - const CLEANING_MODE_MATCHING_TAG = 'matchingTag'; - const CLEANING_MODE_NOT_MATCHING_TAG = 'notMatchingTag'; - const CLEANING_MODE_MATCHING_ANY_TAG = 'matchingAnyTag'; - - /** - * Factory - * - * @param mixed $frontend frontend name (string) or Zend_Cache_Frontend_ object - * @param mixed $backend backend name (string) or Zend_Cache_Backend_ object - * @param array $frontendOptions associative array of options for the corresponding frontend constructor - * @param array $backendOptions associative array of options for the corresponding backend constructor - * @param boolean $customFrontendNaming if true, the frontend argument is used as a complete class name ; if false, the frontend argument is used as the end of "Zend_Cache_Frontend_[...]" class name - * @param boolean $customBackendNaming if true, the backend argument is used as a complete class name ; if false, the backend argument is used as the end of "Zend_Cache_Backend_[...]" class name - * @param boolean $autoload if true, there will no require_once for backend and frontend (useful only for custom backends/frontends) - * @throws Zend_Cache_Exception - * @return Zend_Cache_Core|Zend_Cache_Frontend - */ - public static function factory($frontend, $backend, $frontendOptions = array(), $backendOptions = array(), $customFrontendNaming = false, $customBackendNaming = false, $autoload = false) - { - if (is_string($backend)) { - $backendObject = self::_makeBackend($backend, $backendOptions, $customBackendNaming, $autoload); - } else { - if ((is_object($backend)) && (in_array('Zend_Cache_Backend_Interface', class_implements($backend)))) { - $backendObject = $backend; - } else { - self::throwException('backend must be a backend name (string) or an object which implements Zend_Cache_Backend_Interface'); - } - } - if (is_string($frontend)) { - $frontendObject = self::_makeFrontend($frontend, $frontendOptions, $customFrontendNaming, $autoload); - } else { - if (is_object($frontend)) { - $frontendObject = $frontend; - } else { - self::throwException('frontend must be a frontend name (string) or an object'); - } - } - $frontendObject->setBackend($backendObject); - return $frontendObject; - } - - /** - * Backend Constructor - * - * @param string $backend - * @param array $backendOptions - * @param boolean $customBackendNaming - * @param boolean $autoload - * @return Zend_Cache_Backend - */ - public static function _makeBackend($backend, $backendOptions, $customBackendNaming = false, $autoload = false) - { - if (!$customBackendNaming) { - $backend = self::_normalizeName($backend); - } - if (in_array($backend, Zend_Cache::$standardBackends)) { - // we use a standard backend - $backendClass = 'Zend_Cache_Backend_' . $backend; - // security controls are explicit - require_once str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php'; - } else { - // we use a custom backend - if (!preg_match('~^[\w\\\\]+$~D', $backend)) { - Zend_Cache::throwException("Invalid backend name [$backend]"); - } - if (!$customBackendNaming) { - // we use this boolean to avoid an API break - $backendClass = 'Zend_Cache_Backend_' . $backend; - } else { - $backendClass = $backend; - } - if (!$autoload) { - $file = str_replace('_', DIRECTORY_SEPARATOR, $backendClass) . '.php'; - if (!(self::_isReadable($file))) { - self::throwException("file $file not found in include_path"); - } - require_once $file; - } - } - return new $backendClass($backendOptions); - } - - /** - * Frontend Constructor - * - * @param string $frontend - * @param array $frontendOptions - * @param boolean $customFrontendNaming - * @param boolean $autoload - * @return Zend_Cache_Core|Zend_Cache_Frontend - */ - public static function _makeFrontend($frontend, $frontendOptions = array(), $customFrontendNaming = false, $autoload = false) - { - if (!$customFrontendNaming) { - $frontend = self::_normalizeName($frontend); - } - if (in_array($frontend, self::$standardFrontends)) { - // we use a standard frontend - // For perfs reasons, with frontend == 'Core', we can interact with the Core itself - $frontendClass = 'Zend_Cache_' . ($frontend != 'Core' ? 'Frontend_' : '') . $frontend; - // security controls are explicit - require_once str_replace('_', DIRECTORY_SEPARATOR, $frontendClass) . '.php'; - } else { - // we use a custom frontend - if (!preg_match('~^[\w\\\\]+$~D', $frontend)) { - Zend_Cache::throwException("Invalid frontend name [$frontend]"); - } - if (!$customFrontendNaming) { - // we use this boolean to avoid an API break - $frontendClass = 'Zend_Cache_Frontend_' . $frontend; - } else { - $frontendClass = $frontend; - } - if (!$autoload) { - $file = str_replace('_', DIRECTORY_SEPARATOR, $frontendClass) . '.php'; - if (!(self::_isReadable($file))) { - self::throwException("file $file not found in include_path"); - } - require_once $file; - } - } - return new $frontendClass($frontendOptions); - } - - /** - * Throw an exception - * - * Note : for perf reasons, the "load" of Zend/Cache/Exception is dynamic - * @param string $msg Message for the exception - * @throws Zend_Cache_Exception - */ - public static function throwException($msg, Exception $e = null) - { - // For perfs reasons, we use this dynamic inclusion - require_once 'Zend/Cache/Exception.php'; - throw new Zend_Cache_Exception($msg, 0, $e); - } - - /** - * Normalize frontend and backend names to allow multiple words TitleCased - * - * @param string $name Name to normalize - * @return string - */ - protected static function _normalizeName($name) - { - $name = ucfirst(strtolower($name)); - $name = str_replace(array('-', '_', '.'), ' ', $name); - $name = ucwords($name); - $name = str_replace(' ', '', $name); - if (stripos($name, 'ZendServer') === 0) { - $name = 'ZendServer_' . substr($name, strlen('ZendServer')); - } - - return $name; - } - - /** - * Returns TRUE if the $filename is readable, or FALSE otherwise. - * This function uses the PHP include_path, where PHP's is_readable() - * does not. - * - * Note : this method comes from Zend_Loader (see #ZF-2891 for details) - * - * @param string $filename - * @return boolean - */ - private static function _isReadable($filename) - { - if (!$fh = @fopen($filename, 'r', true)) { - return false; - } - @fclose($fh); - return true; - } - -} diff --git a/includes/libs/DbSimple/Zend/Cache/Backend/Interface.php b/includes/libs/DbSimple/Zend/Cache/Backend/Interface.php deleted file mode 100644 index 3f44e2e1..00000000 --- a/includes/libs/DbSimple/Zend/Cache/Backend/Interface.php +++ /dev/null @@ -1,99 +0,0 @@ -<?php -/** - * Zend Framework - * - * LICENSE - * - * This source file is subject to the new BSD license that is bundled - * with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://framework.zend.com/license/new-bsd - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@zend.com so we can send you a copy immediately. - * - * @category Zend - * @package Zend_Cache - * @subpackage Zend_Cache_Backend - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - * @version $Id: Interface.php 24593 2012-01-05 20:35:02Z matthew $ - */ - - -/** - * @package Zend_Cache - * @subpackage Zend_Cache_Backend - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -interface Zend_Cache_Backend_Interface -{ - /** - * Set the frontend directives - * - * @param array $directives assoc of directives - */ - public function setDirectives($directives); - - /** - * Test if a cache is available for the given id and (if yes) return it (false else) - * - * Note : return value is always "string" (unserialization is done by the core not by the backend) - * - * @param string $id Cache id - * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested - * @return string|false cached datas - */ - public function load($id, $doNotTestCacheValidity = false); - - /** - * Test if a cache is available or not (for the given id) - * - * @param string $id cache id - * @return mixed|false (a cache is not available) or "last modified" timestamp (int) of the available cache record - */ - public function test($id); - - /** - * Save some string datas into a cache record - * - * Note : $data is always "string" (serialization is done by the - * core not by the backend) - * - * @param string $data Datas to cache - * @param string $id Cache id - * @param array $tags Array of strings, the cache record will be tagged by each string entry - * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) - * @return boolean true if no problem - */ - public function save($data, $id, $tags = array(), $specificLifetime = false); - - /** - * Remove a cache record - * - * @param string $id Cache id - * @return boolean True if no problem - */ - public function remove($id); - - /** - * Clean some cache records - * - * Available modes are : - * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) - * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} - * ($tags can be an array of strings or a single string) - * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags - * ($tags can be an array of strings or a single string) - * - * @param string $mode Clean mode - * @param array $tags Array of tags - * @return boolean true if no problem - */ - public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()); - -} diff --git a/includes/type.class.php b/includes/type.class.php index 822b31f1..6676009b 100644 --- a/includes/type.class.php +++ b/includes/type.class.php @@ -152,7 +152,7 @@ abstract class Type if (!(self::$data[$type][self::IDX_FLAGS] & self::FLAG_DB_TYPE)) return []; - return DB::Aowow()->selectCol('SELECT `id` FROM ?# WHERE `id` IN (?a)', self::$data[$type][self::IDX_LIST_OBJ]::$dataTable, (array)$ids); + return DB::Aowow()->selectCol('SELECT `id` FROM %n WHERE `id` IN %in', self::$data[$type][self::IDX_LIST_OBJ]::$dataTable, (array)$ids); } public static function hasIcon(int $type) : bool diff --git a/includes/user.class.php b/includes/user.class.php index d0faba8b..9fa1bd59 100644 --- a/includes/user.class.php +++ b/includes/user.class.php @@ -74,12 +74,12 @@ class User # check IP bans # - if ($ipBan = DB::Aowow()->selectRow('SELECT `count`, IF(`unbanDate` > UNIX_TIMESTAMP(), 1, 0) AS "active" FROM ?_account_bannedips WHERE `ip` = ? AND `type` = ?d', self::$ip, IP_BAN_TYPE_LOGIN_ATTEMPT)) + if ($ipBan = DB::Aowow()->selectRow('SELECT `count`, IF(`unbanDate` > UNIX_TIMESTAMP(), 1, 0) AS "active" FROM ::account_bannedips WHERE `ip` = %s AND `type` = %i', self::$ip, IP_BAN_TYPE_LOGIN_ATTEMPT)) { if ($ipBan['count'] > Cfg::get('ACC_FAILED_AUTH_COUNT') && $ipBan['active']) return false; else if (!$ipBan['active']) - DB::Aowow()->query('DELETE FROM ?_account_bannedips WHERE `ip` = ?', self::$ip); + DB::Aowow()->qry('DELETE FROM ::account_bannedips WHERE `ip` = %s', self::$ip); } @@ -88,13 +88,13 @@ class User if (empty($_SESSION['user'])) return false; - $session = DB::Aowow()->selectRow('SELECT `userId`, `expires` FROM ?_account_sessions WHERE `status` = ?d AND `sessionId` = ?', SESSION_ACTIVE, session_id()); + $session = DB::Aowow()->selectRow('SELECT `userId`, `expires` FROM ::account_sessions WHERE `status` = %i AND `sessionId` = %s', SESSION_ACTIVE, session_id()); $userData = DB::Aowow()->selectRow( 'SELECT a.`id`, a.`passHash`, a.`username`, a.`locale`, a.`userGroups`, a.`userPerms`, BIT_OR(ab.`typeMask`) AS "bans", IFNULL(SUM(r.`amount`), 0) AS "reputation", a.`dailyVotes`, a.`excludeGroups`, a.`status`, a.`statusTimer`, a.`email`, a.`debug`, a.`avatar`, a.`avatarborder` - FROM ?_account a - LEFT JOIN ?_account_banned ab ON a.`id` = ab.`userId` AND ab.`end` > UNIX_TIMESTAMP() - LEFT JOIN ?_account_reputation r ON a.`id` = r.`userId` - WHERE a.`id` = ?d + FROM ::account a + LEFT JOIN ::account_banned ab ON a.`id` = ab.`userId` AND ab.`end` > UNIX_TIMESTAMP() + LEFT JOIN ::account_reputation r ON a.`id` = r.`userId` + WHERE a.`id` = %i GROUP BY a.`id`', $_SESSION['user'] ); @@ -106,20 +106,20 @@ class User } else if ($session['expires'] && $session['expires'] < time()) { - DB::Aowow()->query('UPDATE ?_account_sessions SET `touched` = ?d, `status` = ?d WHERE `sessionId` = ?', time(), SESSION_EXPIRED, session_id()); + DB::Aowow()->qry('UPDATE ::account_sessions SET `touched` = %i, `status` = %i WHERE `sessionId` = %s', time(), SESSION_EXPIRED, session_id()); self::destroy(); return false; } else if ($session['userId'] != $userData['id']) // what in the name of fuck..? { // Don't know why, don't know how .. doesn't matter, both parties are out. - DB::Aowow()->query('UPDATE ?_account_sessions SET `touched` = ?d, `status` = ?d WHERE `userId` IN (?a) AND `status` = ?d', time(), SESSION_FORCED_LOGOUT, [$userData['id'], $session['userId']], SESSION_ACTIVE); + DB::Aowow()->qry('UPDATE ::account_sessions SET `touched` = %i, `status` = %i WHERE `userId` IN %in AND `status` = %i', time(), SESSION_FORCED_LOGOUT, [$userData['id'], $session['userId']], SESSION_ACTIVE); trigger_error('User::init - tried to resume session "'.session_id().'" of user #'.$_SESSION['user'].' linked to session data for user #'.$session['userId'].' Kicked both!', E_USER_ERROR); self::destroy(); return false; } - DB::Aowow()->query('UPDATE ?_account_sessions SET `touched` = ?d, `expires` = IF(`expires`, ?d, 0) WHERE `sessionId` = ?', time(), time() + Cfg::get('SESSION_TIMEOUT_DELAY'), session_id()); + DB::Aowow()->qry('UPDATE ::account_sessions SET `touched` = %i, `expires` = IF(`expires`, %i, 0) WHERE `sessionId` = %s', time(), time() + Cfg::get('SESSION_TIMEOUT_DELAY'), session_id()); if ($loc = Locale::tryFrom($userData['locale'])) self::$preferedLoc = $loc; @@ -127,7 +127,7 @@ class User // reset expired account statuses if ($userData['statusTimer'] && $userData['statusTimer'] < time() && $userData['status'] != ACC_STATUS_NEW) { - DB::Aowow()->query('UPDATE ?_account SET `status` = ?d, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `id` = ?d', ACC_STATUS_NONE, User::$id); + DB::Aowow()->qry('UPDATE ::account SET `status` = %i, `statusTimer` = 0, `token` = "", `updateValue` = "" WHERE `id` = %i', ACC_STATUS_NONE, User::$id); $userData['status'] = ACC_STATUS_NONE; } @@ -156,8 +156,8 @@ class User { if ($userData['avatar'] == 2) { - DB::Aowow()->query('UPDATE ?_account SET `avatar` = 1 WHERE `id` = ?d', self::$id); - DB::Aowow()->query('UPDATE ?_account_avatars SET `current` = 0 WHERE `userId` = ?d', self::$id); + DB::Aowow()->qry('UPDATE ::account SET `avatar` = 1 WHERE `id` = %i', self::$id); + DB::Aowow()->qry('UPDATE ::account_avatars SET `current` = 0 WHERE `userId` = %i', self::$id); } // avatar borders @@ -169,17 +169,17 @@ class User if (!self::isBanned()) { - $lastLogin = DB::Aowow()->selectCell('SELECT `curLogin` FROM ?_account WHERE `id` = ?d', self::$id); + $lastLogin = DB::Aowow()->selectCell('SELECT `curLogin` FROM ::account WHERE `id` = %i', self::$id); // either the day changed or the last visit was >24h ago if (date('j', $lastLogin) != date('j') || (time() - $lastLogin) > 1 * DAY) { // - daily votes (we need to reset this one) self::$dailyVotes = self::getMaxDailyVotes(); - DB::Aowow()->query( - 'UPDATE ?_account - SET `dailyVotes` = ?d, `prevLogin` = `curLogin`, `curLogin` = UNIX_TIMESTAMP(), `prevIP` = `curIP`, `curIP` = ? - WHERE `id` = ?d', + DB::Aowow()->qry( + 'UPDATE ::account + SET `dailyVotes` = %i, `prevLogin` = `curLogin`, `curLogin` = UNIX_TIMESTAMP(), `prevIP` = `curIP`, `curIP` = ? + WHERE `id` = %i', self::$dailyVotes, self::$ip, self::$id @@ -191,9 +191,9 @@ class User // - increment consecutive visits (next day or first of new month and not more than 48h) if ((date('j', $lastLogin) + 1 == date('j') || (date('j') == 1 && date('n', $lastLogin) != date('n'))) && (time() - $lastLogin) < 2 * DAY) - DB::Aowow()->query('UPDATE ?_account SET `consecutiveVisits` = `consecutiveVisits` + 1 WHERE `id` = ?d', self::$id); + DB::Aowow()->qry('UPDATE ::account SET `consecutiveVisits` = `consecutiveVisits` + 1 WHERE `id` = %i', self::$id); else - DB::Aowow()->query('UPDATE ?_account SET `consecutiveVisits` = 0 WHERE `id` = ?d', self::$id); + DB::Aowow()->qry('UPDATE ::account SET `consecutiveVisits` = 0 WHERE `id` = %i', self::$id); } } @@ -207,7 +207,7 @@ class User // $_SESSION['dataKey'] does not depend on user login status and is set in User::init() if (self::isLoggedIn() && $toDB) - DB::Aowow()->query('UPDATE ?_account SET `locale` = ? WHERE `id` = ?', self::$preferedLoc->value, self::$id); + DB::Aowow()->qry('UPDATE ::account SET `locale` = %s WHERE `id` = %s', self::$preferedLoc->value, self::$id); } public static function destroy() @@ -258,11 +258,11 @@ class User return AUTH_INTERNAL_ERR; // handle login try limitation - $ipBan = DB::Aowow()->selectRow('SELECT `ip`, `count`, IF(`unbanDate` > UNIX_TIMESTAMP(), 1, 0) AS "active" FROM ?_account_bannedips WHERE `type` = ?d AND `ip` = ?', IP_BAN_TYPE_LOGIN_ATTEMPT, self::$ip); + $ipBan = DB::Aowow()->selectRow('SELECT `ip`, `count`, IF(`unbanDate` > UNIX_TIMESTAMP(), 1, 0) AS "active" FROM ::account_bannedips WHERE `type` = %i AND `ip` = %s', IP_BAN_TYPE_LOGIN_ATTEMPT, self::$ip); if (!$ipBan || !$ipBan['active']) // no entry exists or time expired; set count to 1 - DB::Aowow()->query('REPLACE INTO ?_account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (?, ?d, 1, UNIX_TIMESTAMP() + ?d)', self::$ip, IP_BAN_TYPE_LOGIN_ATTEMPT, Cfg::get('ACC_FAILED_AUTH_BLOCK')); + DB::Aowow()->qry('REPLACE INTO ::account_bannedips (`ip`, `type`, `count`, `unbanDate`) VALUES (%s, %i, 1, UNIX_TIMESTAMP() + %i)', self::$ip, IP_BAN_TYPE_LOGIN_ATTEMPT, Cfg::get('ACC_FAILED_AUTH_BLOCK')); else // entry already exists; increment count - DB::Aowow()->query('UPDATE ?_account_bannedips SET `count` = `count` + 1, `unbanDate` = UNIX_TIMESTAMP() + ?d WHERE `ip` = ?', Cfg::get('ACC_FAILED_AUTH_BLOCK'), self::$ip); + DB::Aowow()->qry('UPDATE ::account_bannedips SET `count` = `count` + 1, `unbanDate` = UNIX_TIMESTAMP() + %i WHERE `ip` = %s', Cfg::get('ACC_FAILED_AUTH_BLOCK'), self::$ip); if ($ipBan && $ipBan['count'] >= Cfg::get('ACC_FAILED_AUTH_COUNT') && $ipBan['active']) return AUTH_IPBANNED; @@ -271,12 +271,11 @@ class User $query = DB::Aowow()->SelectRow( 'SELECT a.`id`, a.`passHash`, BIT_OR(ab.`typeMask`) AS "bans", a.`status` - FROM ?_account a - LEFT JOIN ?_account_banned ab ON a.`id` = ab.`userId` AND ab.`end` > UNIX_TIMESTAMP() - WHERE { a.`email` = ? } { a.`login` = ? } AND `status` <> ?d + FROM ::account a + LEFT JOIN ::account_banned ab ON a.`id` = ab.`userId` AND ab.`end` > UNIX_TIMESTAMP() + WHERE %if', $email, 'a.`email` %else a.`login` %end = %s AND `status` <> %i GROUP BY a.`id`', - $email ?: DBSIMPLE_SKIP, - !$email ? $nameOrEmail : DBSIMPLE_SKIP, + $nameOrEmail, ACC_STATUS_DELETED ); @@ -287,7 +286,7 @@ class User return AUTH_WRONGPASS; // successfull auth; clear bans for this IP - DB::Aowow()->query('DELETE FROM ?_account_bannedips WHERE `type` = ?d AND `ip` = ?', IP_BAN_TYPE_LOGIN_ATTEMPT, self::$ip); + DB::Aowow()->qry('DELETE FROM ::account_bannedips WHERE `type` = %i AND `ip` = %s', IP_BAN_TYPE_LOGIN_ATTEMPT, self::$ip); if ($query['bans'] & (ACC_BAN_PERM | ACC_BAN_TEMP)) return AUTH_BANNED; @@ -302,7 +301,7 @@ class User if (!DB::isConnectable(DB_AUTH)) return AUTH_INTERNAL_ERR; - $wow = DB::Auth()->selectRow('SELECT a.id, a.salt, a.verifier, ab.active AS hasBan FROM account a LEFT JOIN account_banned ab ON ab.id = a.id AND active <> 0 WHERE username = ? LIMIT 1', $name); + $wow = DB::Auth()->selectRow('SELECT a.id, a.salt, a.verifier, ab.active AS hasBan FROM account a LEFT JOIN account_banned ab ON ab.id = a.id AND active <> 0 WHERE username = %s LIMIT 1', $name); if (!$wow) return AUTH_WRONGUSER; @@ -358,14 +357,14 @@ class User // create a linked account for our settings if necessary private static function checkOrCreateInDB(int $extId, string $name, int $userGroup = -1) : int { - if ($_ = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE `extId` = ?d', $extId)) + if ($_ = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE `extId` = %i', $extId)) { if ($userGroup >= U_GROUP_NONE) - DB::Aowow()->query('UPDATE ?_account SET `userGroups` = ?d WHERE `extId` = ?d', $userGroup, $extId); + DB::Aowow()->qry('UPDATE ::account SET `userGroups` = %i WHERE `extId` = %i', $userGroup, $extId); return $_; } - $newId = DB::Aowow()->query('INSERT IGNORE INTO ?_account (`extId`, `passHash`, `username`, `joinDate`, `prevIP`, `prevLogin`, `locale`, `status`, `userGroups`) VALUES (?d, "", ?, UNIX_TIMESTAMP(), ?, UNIX_TIMESTAMP(), ?d, ?d, ?d)', + $newId = DB::Aowow()->qry('INSERT IGNORE INTO ::account (`extId`, `passHash`, `username`, `joinDate`, `prevIP`, `prevLogin`, `locale`, `status`, `userGroups`) VALUES (%i, "", %s, UNIX_TIMESTAMP(), %s, UNIX_TIMESTAMP(), %i, %i, %i)', $extId, $name, $_SERVER["REMOTE_ADDR"] ?? '', @@ -510,7 +509,7 @@ class User return; self::$dailyVotes--; - DB::Aowow()->query('UPDATE ?_account SET `dailyVotes` = ?d WHERE `id` = ?d', self::$dailyVotes, self::$id); + DB::Aowow()->qry('UPDATE ::account SET `dailyVotes` = %i WHERE `id` = %i', self::$dailyVotes, self::$id); } public static function getCurrentDailyVotes() : int @@ -601,11 +600,11 @@ class User if (!self::isLoggedIn() || self::isBanned()) return $result; - $res = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `name` FROM ?_account_weightscales WHERE `userId` = ?d', self::$id); + $res = DB::Aowow()->selectPairs('SELECT `id`, `name` FROM ::account_weightscales WHERE `userId` = %i', self::$id); if (!$res) return $result; - $weights = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `field` AS ARRAY_KEY2, `val` FROM ?_account_weightscale_data WHERE `id` IN (?a)', array_keys($res)); + $weights = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `field` AS ARRAY_KEY2, `val` FROM ::account_weightscale_data WHERE `id` IN %in', array_keys($res)); foreach ($weights as $id => $data) $result[] = array_merge(['name' => $res[$id], 'id' => $id], $data); @@ -622,9 +621,8 @@ class User if (!Cfg::get('PROFILER_ENABLE')) return $result; - $modes = [1 => 'excludes', 2 => 'includes']; - foreach ($modes as $mode => $field) - if ($ex = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, `typeId` AS ARRAY_KEY2, `typeId` FROM ?_account_excludes WHERE `mode` = ?d AND `userId` = ?d', $mode, self::$id)) + foreach ([Profiler::COMPLETION_EXCLUDE => 'excludes', Profiler::COMPLETION_INCLUDE => 'includes'] as $mode => $field) + if ($ex = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, `typeId` AS ARRAY_KEY2, `typeId` FROM ::account_excludes WHERE `mode` = %i AND `userId` = %i', $mode, self::$id)) foreach ($ex as $type => $ids) $result[$field][$type] = array_values($ids); @@ -673,7 +671,7 @@ class User if (!self::isLoggedIn() || self::isBanned(ACC_BAN_GUIDE)) return $result; - if ($guides = DB::Aowow()->select('SELECT `id`, `title`, `url` FROM ?_guides WHERE `userId` = ?d AND `status` <> ?d', self::$id, GuideMgr::STATUS_ARCHIVED)) + if ($guides = DB::Aowow()->selectAssoc('SELECT `id`, `title`, `url` FROM ::guides WHERE `userId` = %i AND `status` <> %i', self::$id, GuideMgr::STATUS_ARCHIVED)) { // fix url array_walk($guides, fn(&$x) => $x['url'] = '?guide='.($x['url'] ?: $x['id'])); @@ -688,7 +686,7 @@ class User if (!self::isLoggedIn()) return []; - return DB::Aowow()->selectCol('SELECT `name` AS ARRAY_KEY, `data` FROM ?_account_cookies WHERE `userId` = ?d', self::$id); + return DB::Aowow()->selectPairs('SELECT `name`, `data` FROM ::account_cookies WHERE `userId` = %i', self::$id); } public static function getFavorites() : array @@ -696,14 +694,14 @@ class User if (!self::isLoggedIn() || self::isBanned()) return []; - $res = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, `typeId` AS ARRAY_KEY2, `typeId` FROM ?_account_favorites WHERE `userId` = ?d', self::$id); + $res = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, `typeId` AS ARRAY_KEY2, `typeId` FROM ::account_favorites WHERE `userId` = %i', self::$id); if (!$res) return []; $data = []; foreach ($res as $type => $ids) { - $tc = Type::newList($type, [['id', array_values($ids)]]); + $tc = Type::newList($type, [['id', $ids]]); if (!$tc || $tc->error) continue; @@ -733,23 +731,23 @@ class User $completion = []; - $x = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `questId` AS ARRAY_KEY2, `questId` FROM ?_profiler_completion_quests WHERE `id` IN (?a)', $ids); + $x = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `questId` AS ARRAY_KEY2, `questId` FROM ::profiler_completion_quests WHERE `id` IN %in', $ids); $completion[Type::QUEST] = $x ? array_map(array_values(...), $x) : []; - $x = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `achievementId` AS ARRAY_KEY2, `achievementId` FROM ?_profiler_completion_achievements WHERE `id` IN (?a)', $ids); + $x = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `achievementId` AS ARRAY_KEY2, `achievementId` FROM ::profiler_completion_achievements WHERE `id` IN %in', $ids); $completion[Type::ACHIEVEMENT] = $x ? array_map(array_values(...), $x) : []; - $x = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `titleId` AS ARRAY_KEY2, `titleId` FROM ?_profiler_completion_titles WHERE `id` IN (?a)', $ids); + $x = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `titleId` AS ARRAY_KEY2, `titleId` FROM ::profiler_completion_titles WHERE `id` IN %in', $ids); $completion[Type::TITLE] = $x ? array_map(array_values(...), $x) : []; $completion[Type::ITEM] = []; - $spells = DB::Aowow()->select( + $spells = DB::Aowow()->selectAssoc( 'SELECT pcs.`id` AS ARRAY_KEY, pcs.`spellId` AS ARRAY_KEY2, pcs.`spellId`, i.`id` AS "itemId" - FROM ?_spell s - JOIN ?_profiler_completion_spells pcs ON s.`id` = pcs.`spellId` - LEFT JOIN ?_items i ON i.`spellId1` IN (?a) AND i.`spellId2` = pcs.`spellId` - WHERE s.`typeCat` IN (?a) AND pcs.`id` IN (?a)', + FROM ::spell s + JOIN ::profiler_completion_spells pcs ON s.`id` = pcs.`spellId` + LEFT JOIN ::items i ON i.`spellId1` IN %in AND i.`spellId2` = pcs.`spellId` + WHERE s.`typeCat` IN %in AND pcs.`id` IN %in', LEARN_SPELLS, [-5, -6, 9, 11], $ids ); @@ -780,10 +778,10 @@ class User if (self::$profiles === null) { - $ap = DB::Aowow()->selectCol('SELECT `profileId` FROM ?_account_profiles WHERE `accountId` = ?d', self::$id); + $ap = DB::Aowow()->selectCol('SELECT `profileId` FROM ::account_profiles WHERE `accountId` = %i', self::$id); - // 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]]; + // the old approach [DB::OR, ['user', self::$id], ['ap.accountId', self::$id]] caused keys to not get used + $conditions = $ap ? [[DB::OR, ['user', self::$id], ['id', $ap]]] : [['user', self::$id]]; if (!self::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU)) $conditions[] = ['deleted', 0]; diff --git a/includes/utilities.php b/includes/utilities.php index d04d46c3..6f01d15e 100644 --- a/includes/utilities.php +++ b/includes/utilities.php @@ -175,7 +175,7 @@ abstract class Util '/\$g\s*([^:;]*)\s*:\s*([^:;]*)\s*(:?[^:;]*);/ui',// directed gender-reference $g<male>:<female>:<refVariable> '/\$t([^;]+);/ui', // HK rank. $t<male>:<female>; (maybe male/female if pvp unranked? Gets replaced with current HK rank.) '/<([^\"=\/>]+\s[^\"=\/>]+)>/ui', // emotes (workaround: at least one whitespace and never " or = between brackets) - '/\$(\d+)w/ui', // worldState(?)-ref found on some pageTexts $1234w + '/\$(\d+)w/ui', // worldState(%d)-ref found on some pageTexts $1234w '/\$c/i', // class-ref '/\$r/i', // race-ref '/\$n/i', // name-ref @@ -617,8 +617,8 @@ abstract class Util if (empty($miscData['id']) || empty($miscData['voterId'])) return false; - DB::Aowow()->query( // delete old votes the user has cast - 'DELETE FROM ?_account_reputation WHERE sourceA = ?d AND sourceB = ?d AND userId = ?d AND action IN (?a)', + DB::Aowow()->qry( // delete old votes the user has cast + 'DELETE FROM ::account_reputation WHERE sourceA = %i AND sourceB = %i AND userId = %i AND action IN %in', $miscData['id'], $miscData['voterId'], $user, @@ -662,13 +662,13 @@ abstract class Util break; } - $x = array_merge($x, array( + $x += array( 'userId' => $user, 'action' => $action, - 'date' => !empty($miscData['date']) ? $miscData['date'] : time() - )); + 'date' => $miscData['date'] ?? time() + ); - return DB::Aowow()->query('INSERT IGNORE INTO ?_account_reputation (?#) VALUES (?a)', array_keys($x), array_values($x)); + return DB::Aowow()->qry('INSERT IGNORE INTO ::account_reputation %v', $x); } public static function toJSON($data, $forceFlags = 0) @@ -687,37 +687,6 @@ abstract class Util return $json; } - public static function createSqlBatchInsert(array $data) : array - { - if (!count($data) || !is_array(reset($data))) - return []; - - $nRows = 100; - $nItems = count(reset($data)); - $result = []; - $buff = []; - - foreach ($data as $d) - { - if (count($d) != $nItems) - return []; - - $d = array_map(fn($x) => $x === null ? 'NULL' : DB::Aowow()->escape($x), $d); - - $buff[] = implode(',', $d); - - if (count($buff) >= $nRows) - { - $result[] = '('.implode('),(', $buff).')'; - $buff = []; - } - } - - if ($buff) - $result[] = '('.implode('),(', $buff).')'; - - return $result; - } /*****************/ /* file handling */ @@ -871,7 +840,7 @@ abstract class Util { // prepare score-lookup if (empty(self::$perfectGems)) - self::$perfectGems = DB::World()->selectCol('SELECT perfectItemType FROM skill_perfect_item_template WHERE requiredSpecialization = ?d', 55534); + self::$perfectGems = DB::World()->selectCol('SELECT perfectItemType FROM skill_perfect_item_template WHERE requiredSpecialization = %i', 55534); // epic - WotLK - increased stats / profession specific (Dragon's Eyes) if ($profSpec) diff --git a/localization/lang.class.php b/localization/lang.class.php index 006d2ee1..7579c1de 100644 --- a/localization/lang.class.php +++ b/localization/lang.class.php @@ -257,7 +257,7 @@ class Lang { $locks = []; $ids = []; - $lock = DB::Aowow()->selectRow('SELECT * FROM ?_lock WHERE `id` = ?d', $lockId); + $lock = DB::Aowow()->selectRow('SELECT * FROM ::lock WHERE `id` = %i', $lockId); if (!$lock) return $locks; @@ -709,7 +709,7 @@ class Lang $spfVars[0] = $linkType; break; case 'talent': - if ($spell = DB::Aowow()->selectCell('SELECT `spell` FROM ?_talents WHERE `id` = ?d AND `rank` = ?d', $linkVars[0], $linkVars[1])) + if ($spell = DB::Aowow()->selectCell('SELECT `spell` FROM ::talents WHERE `id` = %i AND `rank` = %i', $linkVars[0], $linkVars[1])) { $spfVars[0] = 'spell'; $spfVars[1] = $spell; @@ -778,7 +778,7 @@ class Lang if (preg_match('/\P{Cyrillic}/iu', $word)) // not in cyrillic script return $word; - if ($declWord = DB::Aowow()->selectCell('SELECT dwc.`word` FROM ?_declinedwordcases dwc JOIN ?_declinedword dc ON dwc.`wordId` = dc.`id` WHERE dwc.`caseIdx` = ?d AND dc.`word` = ?', $caseIdx, $word)) + if ($declWord = DB::Aowow()->selectCell('SELECT dwc.`word` FROM ::declinedwordcases dwc JOIN ::declinedword dc ON dwc.`wordId` = dc.`id` WHERE dwc.`caseIdx` = %i AND dc.`word` = %s', $caseIdx, $word)) return $declWord; return $word; diff --git a/prQueue b/prQueue index 10bd8ac5..20b12827 100755 --- a/prQueue +++ b/prQueue @@ -48,7 +48,7 @@ $error = function (int $type, int $realmGUID, int $realmId, int $fetchResult) : trigger_error('prQueue - [realm: '.$realmId.' '.$what.' guid: '.$realmGUID.'] '.$msg, E_USER_WARNING); - DB::Aowow()->query('UPDATE ?_profiler_sync SET `status` = ?d, `errorCode` = ?d WHERE `realm` = ?d AND `realmGUID` = ?d AND `type` = ?d', PR_QUEUE_STATUS_ERROR, PR_QUEUE_ERROR_CHAR, $realmId, $realmGUID, $type); + DB::Aowow()->qry('UPDATE ::profiler_sync SET `status` = %i, `errorCode` = %i WHERE `realm` = %i AND `realmGUID` = %i AND `type` = %i', PR_QUEUE_STATUS_ERROR, PR_QUEUE_ERROR_CHAR, $realmId, $realmGUID, $type); }; @@ -62,7 +62,7 @@ while (Cfg::get('PROFILER_ENABLE', true)) usleep($wait * 1000 * 1000); } - $row = DB::Aowow()->selectRow('SELECT * FROM ?_profiler_sync WHERE `status` = ?d ORDER BY `requestTime` ASC', PR_QUEUE_STATUS_WAITING); + $row = DB::Aowow()->selectRow('SELECT * FROM ::profiler_sync WHERE `status` = %i ORDER BY `requestTime` ASC', PR_QUEUE_STATUS_WAITING); if (!$row) { // nothing more to do @@ -76,12 +76,12 @@ while (Cfg::get('PROFILER_ENABLE', true)) if (empty(Profiler::getRealms()[$row['realm']])) { - DB::Aowow()->query('UPDATE ?_profiler_sync SET `status` = ?d, `errorCode` = ?d WHERE `realm` = ?d AND `type` = ?d AND `typeId` = ?d', PR_QUEUE_STATUS_ERROR, PR_QUEUE_ERROR_ARMORY, $row['realm'], $row['type'], $row['typeId']); + DB::Aowow()->qry('UPDATE ::profiler_sync SET `status` = %i, `errorCode` = %i WHERE `realm` = %i AND `type` = %i AND `typeId` = %i', PR_QUEUE_STATUS_ERROR, PR_QUEUE_ERROR_ARMORY, $row['realm'], $row['type'], $row['typeId']); CLI::write('realm #'.$row['realm'].' for subject guid '.$row['realmGUID'].' is missing/inaccessible.', CLI::LOG_WARN); continue; } else - DB::Aowow()->query('UPDATE ?_profiler_sync SET `status` = ?d WHERE `realm` = ?d AND `type` = ?d AND `typeId` = ?d', PR_QUEUE_STATUS_WORKING, $row['realm'], $row['type'], $row['typeId']); + DB::Aowow()->qry('UPDATE ::profiler_sync SET `status` = %i WHERE `realm` = %i AND `type` = %i AND `typeId` = %i', PR_QUEUE_STATUS_WORKING, $row['realm'], $row['type'], $row['typeId']); switch ($row['type']) { @@ -94,7 +94,7 @@ while (Cfg::get('PROFILER_ENABLE', true)) break 2; case Profiler::FETCH_RESULT_ERR_NAME_EMPTY: case Profiler::FETCH_RESULT_ERR_NOT_FOUND: - DB::Aowow()->query('DELETE FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` = ?d', $row['realm'], $row['realmGUID']); + DB::Aowow()->qry('DELETE FROM ::profiler_profiles WHERE `realm` = %i AND `realmGUID` = %i', $row['realm'], $row['realmGUID']); default: $error(Type::PROFILE, $row['realmGUID'], $row['realm'], $result); continue 3; @@ -107,7 +107,7 @@ while (Cfg::get('PROFILER_ENABLE', true)) case Profiler::FETCH_RESULT_ERR_NAME_EMPTY: case Profiler::FETCH_RESULT_ERR_NOT_FOUND: case Profiler::FETCH_RESULT_ERR_NO_MEMBERS: - DB::Aowow()->query('DELETE FROM ?_profiler_guild WHERE `realm` = ?d AND `realmGUID` = ?d', $row['realm'], $row['realmGUID']); + DB::Aowow()->qry('DELETE FROM ::profiler_guild WHERE `realm` = %i AND `realmGUID` = %i', $row['realm'], $row['realmGUID']); default: $error(Type::GUILD, $row['realmGUID'], $row['realm'], $result); continue 3; @@ -120,20 +120,20 @@ while (Cfg::get('PROFILER_ENABLE', true)) case Profiler::FETCH_RESULT_ERR_NAME_EMPTY: case Profiler::FETCH_RESULT_ERR_NOT_FOUND: case Profiler::FETCH_RESULT_ERR_NO_MEMBERS: - DB::Aowow()->query('DELETE FROM ?_profiler_arena_team WHERE `realm` = ?d AND `realmGUID` = ?d', $row['realm'], $row['realmGUID']); + DB::Aowow()->qry('DELETE FROM ::profiler_arena_team WHERE `realm` = %i AND `realmGUID` = %i', $row['realm'], $row['realmGUID']); default: $error(Type::ARENA_TEAM, $row['realmGUID'], $row['realm'], $result); continue 3; } default: - DB::Aowow()->query('DELETE FROM ?_profiler_sync WHERE realm = ?d AND type = ?d AND typeId = ?d', $row['realm'], $row['type'], $row['typeId']); + DB::Aowow()->qry('DELETE FROM ::profiler_sync WHERE realm = %i AND type = %i AND typeId = %i', $row['realm'], $row['type'], $row['typeId']); trigger_error('prQueue - unknown type #'.$row['type'].' to sync into profiler. Removing from queue...', E_USER_ERROR); } $tCycle = microtime(true); // mark as ready - DB::Aowow()->query('UPDATE ?_profiler_sync SET `status` = ?d, `errorCode` = 0 WHERE `realm` = ?d AND `type` = ?d AND `typeId` = ?d', PR_QUEUE_STATUS_READY, $row['realm'], $row['type'], $row['typeId']); + DB::Aowow()->qry('UPDATE ::profiler_sync SET `status` = %i, `errorCode` = 0 WHERE `realm` = %i AND `type` = %i AND `typeId` = %i', PR_QUEUE_STATUS_READY, $row['realm'], $row['type'], $row['typeId']); } Profiler::queueFree(); diff --git a/setup/tools/CLISetup.class.php b/setup/tools/CLISetup.class.php index 670274bd..8ea9efd2 100644 --- a/setup/tools/CLISetup.class.php +++ b/setup/tools/CLISetup.class.php @@ -651,7 +651,7 @@ class CLISetup return false; } - if (DB::Aowow()->selectCell('SHOW TABLES LIKE ?', 'dbc_'.$name) && DB::Aowow()->selectCell('SELECT count(1) FROM ?#', 'dbc_'.$name)) + if (DB::Aowow()->selectCell('SHOW TABLES LIKE %s', 'dbc_'.$name) && DB::Aowow()->selectCell('SELECT count(1) FROM %n', 'dbc_'.$name)) return true; $dbc = new DBC($name, ['temporary' => self::getOpt('delete')]); diff --git a/setup/tools/clisetup/account.us.php b/setup/tools/clisetup/account.us.php index 9ac77d0b..905ae979 100644 --- a/setup/tools/clisetup/account.us.php +++ b/setup/tools/clisetup/account.us.php @@ -64,16 +64,16 @@ CLISetup::registerUtility(new class extends UtilityScript else $email = ''; - if ($this->fields && CLI::read($this->fields, $uiAccount)) + if ($this->fields && CLI::read($this->fields, $uiAccount) && $uiAccount) { CLI::write(); - if (!$name && !Util::validateUsername($uiAccount['name'], $e)) + if (!$name && !Util::validateUsername($uiAccount['name'], $e) && $e) CLI::write(Lang::account($e == 1 ? 'errNameLength' : 'errNameChars'), CLI::LOG_ERROR); else if (!$name) $name = $uiAccount['name']; - if (!$passw && !Util::validatePassword($uiAccount['pass1'], $e)) + if (!$passw && !Util::validatePassword($uiAccount['pass1'], $e) && $e) CLI::write($e == 1 ? Lang::account('errPassLength') : Lang::main('intError'), CLI::LOG_ERROR); else if (!$passw && $uiAccount['pass1'] != $uiAccount['pass2']) CLI::write(Lang::account('passMismatch'), CLI::LOG_ERROR); @@ -99,17 +99,17 @@ CLISetup::registerUtility(new class extends UtilityScript if (!$name || !$passw || !$email) return false; - if ($username = DB::Aowow()->selectCell('SELECT `username` FROM ?_account WHERE (LOWER(`username`) = LOWER(?) OR LOWER(`email`) = LOWER(?)) AND (`status` <> ?d OR (`status` = ?d AND `statusTimer` > UNIX_TIMESTAMP()))', $name, $email, ACC_STATUS_NEW, ACC_STATUS_NEW)) + if ($username = DB::Aowow()->selectCell('SELECT `username` FROM ::account WHERE (LOWER(`username`) = LOWER(%s) OR LOWER(`email`) = LOWER(%s)) AND (`status` <> %i OR (`status` = %i AND `statusTimer` > UNIX_TIMESTAMP()))', $name, $email, ACC_STATUS_NEW, ACC_STATUS_NEW)) { CLI::write('[account] ' . (Util::lower($name) == Util::lower($username) ? Lang::account('nameInUse') : Lang::account('mailInUse')), CLI::LOG_ERROR); CLI::write(); return false; } - if (DB::Aowow()->query('REPLACE INTO ?_account (`login`, `passHash`, `username`, `joindate`, `email`, `userGroups`, `userPerms`) VALUES (?, ?, ?, UNIX_TIMESTAMP(), ?, ?d, 1)', + if (DB::Aowow()->qry('REPLACE INTO ::account (`login`, `passHash`, `username`, `joindate`, `email`, `userGroups`, `userPerms`) VALUES (%s, %s, %s, UNIX_TIMESTAMP(), %s, %i, 1)', $name, User::hashCrypt($passw), $name, $email, U_GROUP_ADMIN)) { - $newId = DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE LOWER(`username`) = LOWER(?)', $name); + $newId = DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE LOWER(`username`) = LOWER(%s)', $name); Util::gainSiteReputation($newId, SITEREP_ACTION_REGISTER); CLI::write("[account] admin ".$name." created successfully", CLI::LOG_OK); @@ -127,7 +127,7 @@ CLISetup::registerUtility(new class extends UtilityScript public function test(?array &$error = []) : bool { $error = []; - return !!DB::Aowow()->selectCell('SELECT `id` FROM ?_account WHERE `userPerms` = 1'); + return !!DB::Aowow()->selectCell('SELECT `id` FROM ::account WHERE `userPerms` = 1'); } }); diff --git a/setup/tools/clisetup/datagen.us.php b/setup/tools/clisetup/datagen.us.php index 11385ffe..03491690 100644 --- a/setup/tools/clisetup/datagen.us.php +++ b/setup/tools/clisetup/datagen.us.php @@ -111,6 +111,14 @@ CLISetup::registerUtility(new class extends UtilityScript CLI::write('[sql] subscript \''.$cmd.'\' returned '.($success ? 'successfully' : 'with errors'), $success ? CLI::LOG_OK : CLI::LOG_ERROR); CLI::write(); set_time_limit($this->defaultExecTime); // reset to default for the next script + + // try to free memory + unset($scriptRef, $this->generators[$cmd]); + if (gc_enabled()) + { + gc_collect_cycles(); + gc_mem_caches(); + } } return $allOk; diff --git a/setup/tools/clisetup/dbconfig.us.php b/setup/tools/clisetup/dbconfig.us.php index 71f585ca..35557c61 100644 --- a/setup/tools/clisetup/dbconfig.us.php +++ b/setup/tools/clisetup/dbconfig.us.php @@ -86,7 +86,7 @@ CLISetup::registerUtility(new class extends UtilityScript CLI::write(); if (!DB::isConnectable(DB_AUTH) || !$this->test()) CLI::write('[db] auth server not yet set up.', CLI::LOG_ERROR); - else if ($realms = DB::Auth()->select('SELECT `id` AS "0", `name` AS "1", `icon` AS "2", `timezone` AS "3", `allowedSecurityLevel` AS "4" FROM realmlist')) + else if ($realms = DB::Auth()->selectAssoc('SELECT `id` AS "0", `name` AS "1", `icon` AS "2", `timezone` AS "3", `allowedSecurityLevel` AS "4" FROM realmlist')) { $tbl = [['Realm Id', 'Name', 'Type', 'Region', 'GMLevel', 'Status']]; foreach ($realms as [$id, $name, $icon, $region, $level]) @@ -216,13 +216,13 @@ CLISetup::registerUtility(new class extends UtilityScript switch ($idx) { case DB_AOWOW: - if (DB::Aowow()->selectCell('SHOW TABLES LIKE ?', 'aowow_dbversion')) + if (DB::Aowow()->selectCell('SHOW TABLES LIKE %s', 'aowow_dbversion')) Cfg::load(); // first time load after successful db setup else $error[] = ' * '.$what.': doesn\'t seem to contain aowow tables!'; break; case DB_WORLD: - if (!DB::World()->selectCell('SHOW TABLES LIKE ?', 'version')) + if (!DB::World()->selectCell('SHOW TABLES LIKE %s', 'version')) $error[] = ' * '.$what.': doesn\'t seem to contain TrinityCore world tables!'; else if (DB::World()->selectCell('SELECT `cache_id` FROM `version`') < TDB_WORLD_MINIMUM_VER) $error[] = ' * '.$what.': TDB world db is structurally outdated! (min rev.: '.CLI::bold(TDB_WORLD_MINIMUM_VER).')'; @@ -255,9 +255,9 @@ CLISetup::registerUtility(new class extends UtilityScript switch ($idx) { case DB_AOWOW: - if (DB::Aowow()->selectCell('SHOW TABLES LIKE ?', 'aowow_dbversion')) + if (DB::Aowow()->selectCell('SHOW TABLES LIKE %s', 'aowow_dbversion')) { - if ($date = DB::Aowow()->selectCell('SELECT `date` FROM ?_dbversion')) + if ($date = DB::Aowow()->selectCell('SELECT `date` FROM ::dbversion')) { $note = 'AoWoW DB version @ ' . date(Util::$dateFormatInternal, $date); $ok = true; @@ -269,7 +269,7 @@ CLISetup::registerUtility(new class extends UtilityScript $note = CLI::yellow('DB test failed to find dbversion table. ').CLI::bold('setup/sql/01-db_structure.sql').CLI::yellow(' not yet imported?'); break; case DB_WORLD: - if (DB::World()->selectCell('SHOW TABLES LIKE ?', 'version')) + if (DB::World()->selectCell('SHOW TABLES LIKE %s', 'version')) { [$vString, $vNo] = DB::World()->selectRow('SELECT `db_version` AS "0", `cache_id` AS "1" FROM `version`'); if (strpos($vString, 'TDB') === 0) @@ -289,7 +289,7 @@ CLISetup::registerUtility(new class extends UtilityScript else $note = CLI::yellow('DB test found unexpected vendor in expected version table. Uhh.. Good Luck..!?'); } - else if (DB::World()->selectCell('SHOW TABLES LIKE ?', 'db_version')) + else if (DB::World()->selectCell('SHOW TABLES LIKE %s', 'db_version')) $note = CLI::yellow('DB test found MaNGOS styled version table. MaNGOS DB structure is not supported!'); else $note = CLI::yellow('DB test failed to find version table. TrinityDB world not yet imported?'); diff --git a/setup/tools/clisetup/filegen.us.php b/setup/tools/clisetup/filegen.us.php index 70188e42..426a0769 100644 --- a/setup/tools/clisetup/filegen.us.php +++ b/setup/tools/clisetup/filegen.us.php @@ -126,6 +126,14 @@ CLISetup::registerUtility(new class extends UtilityScript CLI::write(); set_time_limit($this->defaultExecTime); // reset to default for the next script + + // try to free memory + unset($scriptRef, $this->generators[$cmd]); + if (gc_enabled()) + { + gc_collect_cycles(); + gc_mem_caches(); + } } return $allOk; diff --git a/setup/tools/clisetup/sync.us.php b/setup/tools/clisetup/sync.us.php index 05b30367..38d20d81 100644 --- a/setup/tools/clisetup/sync.us.php +++ b/setup/tools/clisetup/sync.us.php @@ -45,14 +45,14 @@ CLISetup::registerUtility(new class extends UtilityScript { $io = ['doSql' => $s, 'doneSql' => []]; CLISetup::run('sql', $io); - DB::Aowow()->query('UPDATE ?_dbversion SET `sql` = ?', implode(' ', array_diff($io['doSql'], $io['doneSql']))); + DB::Aowow()->qry('UPDATE ::dbversion SET `sql` = %s', implode(' ', array_diff($io['doSql'], $io['doneSql']))); } if ($b) { $io = ['doBuild' => $b, 'doneBuild' => []]; CLISetup::run('build', $io); - DB::Aowow()->query('UPDATE ?_dbversion SET `build` = ?', implode(' ', array_diff($io['doBuild'], $io['doneBuild']))); + DB::Aowow()->qry('UPDATE ::dbversion SET `build` = %s', implode(' ', array_diff($io['doBuild'], $io['doneBuild']))); } return true; diff --git a/setup/tools/clisetup/update.us.php b/setup/tools/clisetup/update.us.php index ba957aaa..7f4fd99f 100644 --- a/setup/tools/clisetup/update.us.php +++ b/setup/tools/clisetup/update.us.php @@ -32,7 +32,7 @@ CLISetup::registerUtility(new class extends UtilityScript public function __construct() { if (DB::isConnected(DB_AOWOW)) - [$this->date, $this->part] = array_values(DB::Aowow()->selectRow('SELECT `date`, `part` FROM ?_dbversion')); + [$this->date, $this->part] = array_values(DB::Aowow()->selectRow('SELECT `date`, `part` FROM ::dbversion')); } // args: null, null, sqlToDo, buildToDo // nnoo @@ -75,21 +75,21 @@ CLISetup::registerUtility(new class extends UtilityScript // semicolon at the end -> end of query if (substr(trim($line), -1, 1) == ';') { - if (DB::Aowow()->query($updQuery)) + if (DB::Aowow()->qry($updQuery)) $nQuerys++; $updQuery = ''; } } - DB::Aowow()->query('UPDATE ?_dbversion SET `date`= ?d, `part` = ?d', $fDate, $fPart); + DB::Aowow()->qry('UPDATE ::dbversion SET `date`= %i, `part` = %i', $fDate, $fPart); CLI::write(' -> '.date('d.m.Y', $fDate).' #'.$fPart.': '.$nQuerys.' queries applied', CLI::LOG_OK); } CLI::write('[update] ' . ($nFiles ? 'applied '.$nFiles.' update(s)' : 'db is already up to date'), CLI::LOG_OK); // fetch sql/build after applying updates, as they may contain sync-prompts - [$sql, $build] = DB::Aowow()->selectRow('SELECT `sql` AS "0", `build` AS "1" FROM ?_dbversion'); + [$sql, $build] = DB::Aowow()->selectRow('SELECT `sql` AS "0", `build` AS "1" FROM ::dbversion'); $sql = trim($sql) ? array_unique(explode(' ', trim(preg_replace('/[^a-z_\-]+/i', ' ', $sql)))) : []; $build = trim($build) ? array_unique(explode(' ', trim(preg_replace('/[^a-z_\-]+/i', ' ', $build)))) : []; diff --git a/setup/tools/dbc.class.php b/setup/tools/dbc.class.php index db687f68..c4d4fad1 100644 --- a/setup/tools/dbc.class.php +++ b/setup/tools/dbc.class.php @@ -344,8 +344,8 @@ class DBC $query .= ') COLLATE=\'utf8mb4_unicode_ci\' ENGINE=InnoDB'; - DB::Aowow()->query('DROP TABLE IF EXISTS ?#', $this->tableName); - DB::Aowow()->query($query); + DB::Aowow()->qry('DROP TABLE IF EXISTS %n', $this->tableName); + DB::Aowow()->qry($query); } private function writeToDB() @@ -375,7 +375,9 @@ class DBC if ($this->isGameTable) array_unshift($cols, 'idx'); - DB::Aowow()->query('INSERT INTO ?# (?#) VALUES (?a)', $this->tableName, $cols, $this->dataBuffer); + foreach ($this->dataBuffer as $row) + DB::Aowow()->qry('INSERT INTO %n %v', $this->tableName, array_combine($cols, $row)); + $this->dataBuffer = []; } diff --git a/setup/tools/filegen/enchants.ss.php b/setup/tools/filegen/enchants.ss.php index 4bbb0ad8..bc6521fc 100644 --- a/setup/tools/filegen/enchants.ss.php +++ b/setup/tools/filegen/enchants.ss.php @@ -67,16 +67,16 @@ CLISetup::registerSetup("build", new class extends SetupScript $slotPointer = [13, 17, 15, 15, 13, 17, 17, 13, 17, null, 17, null, null, 13, null, 13, null, null, null, null, 17]; $castItems = []; - $enchantSpells = DB::Aowow()->select( + $enchantSpells = DB::Aowow()->selectAssoc( 'SELECT s.`id` AS ARRAY_KEY, `effect1MiscValue`, `equippedItemClass`, `equippedItemInventoryTypeMask`, `equippedItemSubClassMask`, `skillLine1`, - IFNULL(i.`name`, ?) AS "iconString", + IFNULL(i.`name`, %s) AS "iconString", `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8` - FROM ?_spell s - LEFT JOIN ?_icons i ON i.`id` = s.`iconId` - WHERE `effect1Id` = ?d AND + FROM ::spell s + LEFT JOIN ::icons i ON i.`id` = s.`iconId` + WHERE `effect1Id` = %i AND `name_loc0` NOT LIKE "QA%"', DEFAULT_ICON, SPELL_EFFECT_ENCHANT_ITEM ); @@ -86,7 +86,7 @@ CLISetup::registerSetup("build", new class extends SetupScript $enchantments = new EnchantmentList(array(['id', $enchIds])); if ($enchantments->error) { - CLI::write('[enchants] Required table ?_itemenchantment seems to be empty!', CLI::LOG_ERROR); + CLI::write('[enchants] Required table ::itemenchantment seems to be empty!', CLI::LOG_ERROR); CLI::write(); return false; } @@ -94,7 +94,7 @@ CLISetup::registerSetup("build", new class extends SetupScript $castItems = new ItemList(array(['spellId1', array_keys($enchantSpells)], ['src.typeId', null, '!'])); if ($castItems->error) { - CLI::write('[enchants] Required table ?_items seems to be empty!', CLI::LOG_ERROR); + CLI::write('[enchants] Required table ::items seems to be empty!', CLI::LOG_ERROR); CLI::write(); return false; } diff --git a/setup/tools/filegen/gems.ss.php b/setup/tools/filegen/gems.ss.php index db85ef53..6ab27d67 100644 --- a/setup/tools/filegen/gems.ss.php +++ b/setup/tools/filegen/gems.ss.php @@ -36,18 +36,18 @@ CLISetup::registerSetup("build", new class extends SetupScript { // sketchy, but should work // id < 36'000 || ilevel < 70 ? BC : WOTLK - $gems = DB::Aowow()->select( + $gems = DB::Aowow()->selectAssoc( 'SELECT i.`id` AS "itemId", i.`name_loc0`, i.`name_loc2`, i.`name_loc3`, i.`name_loc4`, i.`name_loc6`, i.`name_loc8`, - IF (i.`id` < 36000 OR i.`itemLevel` < 70, ?d, ?d) AS "expansion", + IF (i.`id` < 36000 OR i.`itemLevel` < 70, %i, %i) AS "expansion", i.`quality`, ic.`name` AS "icon", i.`gemEnchantmentId` AS "enchId", i.`gemColorMask` AS "colors", i.`requiredSkill`, i.`itemLevel` - FROM ?_items i - JOIN ?_icons ic ON ic.`id` = i.`iconId` + FROM ::items i + JOIN ::icons ic ON ic.`id` = i.`iconId` WHERE i.`gemEnchantmentId` <> 0 ORDER BY i.`id` DESC', EXP_BC, EXP_WOTLK @@ -56,7 +56,7 @@ CLISetup::registerSetup("build", new class extends SetupScript $enchantments = new EnchantmentList(array(['id', array_column($gems, 'enchId')])); if ($enchantments->error) { - CLI::write('[gems] Required table ?_itemenchantment seems to be empty!', CLI::LOG_ERROR); + CLI::write('[gems] Required table ::itemenchantment seems to be empty!', CLI::LOG_ERROR); CLI::write(); return false; } diff --git a/setup/tools/filegen/glyphs.ss.php b/setup/tools/filegen/glyphs.ss.php index dc2b03b2..f746276a 100644 --- a/setup/tools/filegen/glyphs.ss.php +++ b/setup/tools/filegen/glyphs.ss.php @@ -33,7 +33,7 @@ CLISetup::registerSetup("build", new class extends SetupScript public function generate() : bool { - $glyphList = DB::Aowow()->Select( + $glyphList = DB::Aowow()->selectAssoc( 'SELECT i.`id` AS "itemId", i.*, IF (g.`typeFlags` & 0x1, 2, 1) AS "type", @@ -44,12 +44,12 @@ CLISetup::registerSetup("build", new class extends SetupScript s1.`skillLine1` AS "skillId", s2.`id` AS "glyphEffect", s2.`id` AS ARRAY_KEY - FROM ?_items i - JOIN ?_spell s1 ON s1.`id` = i.`spellid1` - JOIN ?_glyphproperties g ON g.`id` = s1.`effect1MiscValue` - JOIN ?_spell s2 ON s2.`id` = g.`spellId` - JOIN ?_icons ic ON ic.`id` = s1.`iconIdAlt` - WHERE i.classBak = ?d', + FROM ::items i + JOIN ::spell s1 ON s1.`id` = i.`spellid1` + JOIN ::glyphproperties g ON g.`id` = s1.`effect1MiscValue` + JOIN ::spell s2 ON s2.`id` = g.`spellId` + JOIN ::icons ic ON ic.`id` = s1.`iconIdAlt` + WHERE i.classBak = %i', ITEM_CLASS_GLYPH); $glyphSpells = new SpellList(array(['s.id', array_keys($glyphList)])); diff --git a/setup/tools/filegen/img-maps.ss.php b/setup/tools/filegen/img-maps.ss.php index 3282210b..380129cf 100644 --- a/setup/tools/filegen/img-maps.ss.php +++ b/setup/tools/filegen/img-maps.ss.php @@ -401,9 +401,9 @@ CLISetup::registerSetup("build", new class extends SetupScript private function prepare() : bool { - $this->wmOverlays = DB::Aowow()->select('SELECT *, `worldMapAreaId` AS ARRAY_KEY, `id` AS ARRAY_KEY2 FROM dbc_worldmapoverlay WHERE `textureString` <> ""'); - $this->wmAreas = DB::Aowow()->select('SELECT `id`, `mapId`, `areaId`, UPPER(`nameINT`) AS `nameINT`, IF(`areaId`, `areaId`, -`id`) AS ARRAY_KEY FROM dbc_worldmaparea'); - $this->dmFloorData = DB::Aowow()->select('SELECT IF(`mapId` IN (?a), -`worldMapAreaId`, `mapId`) AS ARRAY_KEY, GROUP_CONCAT(DISTINCT `floor` SEPARATOR " ") AS "0", COUNT(DISTINCT `floor`) AS "1" FROM dbc_dungeonmap WHERE `worldMapAreaId` <> 0 GROUP BY ARRAY_KEY', self::CONTINENTS); + $this->wmOverlays = DB::Aowow()->selectAssoc('SELECT *, `worldMapAreaId` AS ARRAY_KEY, `id` AS ARRAY_KEY2 FROM dbc_worldmapoverlay WHERE `textureString` <> ""'); + $this->wmAreas = DB::Aowow()->selectAssoc('SELECT `id`, `mapId`, `areaId`, UPPER(`nameINT`) AS `nameINT`, IF(`areaId`, `areaId`, -`id`) AS ARRAY_KEY FROM dbc_worldmaparea'); + $this->dmFloorData = DB::Aowow()->selectAssoc('SELECT IF(`mapId` IN %in, -`worldMapAreaId`, `mapId`) AS ARRAY_KEY, GROUP_CONCAT(DISTINCT `floor` SEPARATOR " ") AS "0", COUNT(DISTINCT `floor`) AS "1" FROM dbc_dungeonmap WHERE `worldMapAreaId` <> 0 GROUP BY ARRAY_KEY', self::CONTINENTS); if (!$this->wmOverlays || !$this->wmAreas || !$this->dmFloorData) { CLI::write('[img-maps] - could not read required dbc files: WorldMapArea.dbc ['.count($this->wmAreas ?: []).' entries]; WorldMapOverlay.dbc ['.count($this->wmOverlays ?: []).'] entries; DungeonMap.dbc ['.count($this->dmFloorData ?: []).' entries]', CLI::LOG_ERROR); diff --git a/setup/tools/filegen/img-talentcalc.ss.php b/setup/tools/filegen/img-talentcalc.ss.php index e9ac6a6d..c32221c5 100644 --- a/setup/tools/filegen/img-talentcalc.ss.php +++ b/setup/tools/filegen/img-talentcalc.ss.php @@ -55,7 +55,7 @@ CLISetup::registerSetup("build", new class extends SetupScript sleep(2); - $tTabs = DB::Aowow()->select('SELECT tt.`creatureFamilyMask`, tt.`textureFile`, tt.`tabNumber`, cc.`fileString` FROM dbc_talenttab tt LEFT JOIN dbc_chrclasses cc ON cc.`id` = IF(tt.`classMask`, LOG(2, tt.`classMask`) + 1, 0)'); + $tTabs = DB::Aowow()->selectAssoc('SELECT tt.`creatureFamilyMask`, tt.`textureFile`, tt.`tabNumber`, cc.`fileString` FROM dbc_talenttab tt LEFT JOIN dbc_chrclasses cc ON cc.`id` = IF(tt.`classMask`, LOG(2, tt.`classMask`) + 1, 0)'); if (!$tTabs) { CLI::write(' - TalentTab.dbc or ChrClasses.dbc is empty...?', CLI::LOG_ERROR); diff --git a/setup/tools/filegen/itemscaling.ss.php b/setup/tools/filegen/itemscaling.ss.php index 4613d579..3ddf0b3a 100644 --- a/setup/tools/filegen/itemscaling.ss.php +++ b/setup/tools/filegen/itemscaling.ss.php @@ -74,7 +74,7 @@ CLISetup::registerSetup("build", new class extends SetupScript $offsets = array_map(function ($v) { // LookupEntry(cr*GT_MAX_LEVEL+level-1) return $v * 100 + 60 - 1; // combat rating where introduced during the transition vanilla > burnig crusade. So at level 60 (at the time) the rating on the item was equal to 1% effect and is still the baseline in 3.3.5a. }, $ratings); - $base = DB::Aowow()->selectCol('SELECT CAST((idx + 1 - 60) / 100 AS UNSIGNED) AS ARRAY_KEY, ratio FROM dbc_gtcombatratings WHERE idx IN (?a)', $offsets); + $base = DB::Aowow()->selectCol('SELECT CAST((idx + 1 - 60) / 100 AS UNSIGNED) AS ARRAY_KEY, ratio FROM dbc_gtcombatratings WHERE idx IN %in', $offsets); /* non-1 scaler in 3.3.5.12340 | ratingId | classId | ratio | @@ -88,7 +88,7 @@ CLISetup::registerSetup("build", new class extends SetupScript $offsets = array_map(function ($v) { // LookupEntry((getClass()-1)*GT_MAX_RATING+cr+1) return (ChrClass::WARRIOR->value - 1) * 32 + $v + 1; // should this be dynamic per pinned character? ITEM_MOD HASTE has a worse scaler for a subset of classes (see table) }, $ratings); - $mods = DB::Aowow()->selectCol('SELECT idx - 1 AS ARRAY_KEY, ratio FROM dbc_gtoctclasscombatratingscalar WHERE idx IN (?a)', $offsets); + $mods = DB::Aowow()->selectCol('SELECT idx - 1 AS ARRAY_KEY, ratio FROM dbc_gtoctclasscombatratingscalar WHERE idx IN %in', $offsets); foreach ($data as &$val) $val = Cfg::get('DEBUG') ? $base[$val].' / '.$mods[$val] : $base[$val] / $mods[$val]; @@ -115,7 +115,7 @@ CLISetup::registerSetup("build", new class extends SetupScript $v = $v ?: '0 AS idx'.$k; // NULL => 0 (plus some index so we can have 2x 0) }); - $data = DB::Aowow()->select('SELECT id AS ARRAY_KEY, '.implode(', ', $fields).' FROM dbc_scalingstatvalues'); + $data = DB::Aowow()->selectAssoc('SELECT id AS ARRAY_KEY, '.implode(', ', $fields).' FROM dbc_scalingstatvalues'); foreach ($data as &$d) $d = array_values($d); // strip indizes @@ -124,7 +124,7 @@ CLISetup::registerSetup("build", new class extends SetupScript private function itemScalingSD() : string { - $data = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM dbc_scalingstatdistribution'); + $data = DB::Aowow()->selectAssoc('SELECT *, id AS ARRAY_KEY FROM dbc_scalingstatdistribution'); foreach ($data as &$row) { $row = array_values($row); diff --git a/setup/tools/filegen/itemsets.ss.php b/setup/tools/filegen/itemsets.ss.php index 0280f2ec..3b367648 100644 --- a/setup/tools/filegen/itemsets.ss.php +++ b/setup/tools/filegen/itemsets.ss.php @@ -43,7 +43,7 @@ CLISetup::registerSetup("build", new class extends SetupScript public function generate() : bool { - $setList = DB::Aowow()->Select('SELECT * FROM ?_itemset ORDER BY `refSetId` DESC'); + $setList = DB::Aowow()->selectAssoc('SELECT * FROM ::itemset ORDER BY `refSetId` DESC'); $jsonBonus = []; foreach (CLISetup::$locales as $loc) diff --git a/setup/tools/filegen/pets.ss.php b/setup/tools/filegen/pets.ss.php index 3f96968e..d5f223e4 100644 --- a/setup/tools/filegen/pets.ss.php +++ b/setup/tools/filegen/pets.ss.php @@ -15,7 +15,7 @@ if (!CLI) name:'Forest Spider', minlevel:5, maxlevel:6, - location:[12], // master-AreaTableId's (?) + location:[12], // master-AreaTableId's (%s) react:[-1,-1], classification:0, // 0:"Normal", 1:"Elite", 2:"Rar Elite", 3:"Boss", 4:"Rar" family:3, // creatureFamily @@ -40,7 +40,7 @@ CLISetup::registerSetup("build", new class extends SetupScript public function generate() : bool { - $petList = DB::Aowow()->Select( + $petList = DB::Aowow()->selectAssoc( 'SELECT cr.`id`, cr.`name_loc0`, cr.`name_loc2`, cr.`name_loc3`, cr.`name_loc4`, cr.`name_loc6`, cr.`name_loc8`, cr.`minLevel`, cr.`maxLevel`, @@ -49,17 +49,17 @@ CLISetup::registerSetup("build", new class extends SetupScript cr.`family`, cr.`displayId1` AS "displayId", cr.`textureString` AS "skin", - LOWER(SUBSTRING_INDEX(cf.`iconString`, "\\\\", -1)) AS "icon", + LOWER(SUBSTRING_INDEX(cf.`iconString`, "\\", -1)) AS "icon", cf.`petTalentType` AS "type" - FROM ?_creature cr - JOIN ?_factiontemplate ft ON ft.`id` = cr.`faction` + FROM ::creature cr + JOIN ::factiontemplate ft ON ft.`id` = cr.`faction` JOIN dbc_creaturefamily cf ON cf.`id` = cr.`family` - WHERE cr.`typeFlags` & 0x1 AND (cr.`cuFlags` & ?d) = 0 + WHERE cr.`typeFlags` & 0x1 AND (cr.`cuFlags` & %i) = 0 ORDER BY cr.`id` ASC', NPC_CU_DIFFICULTY_DUMMY ); - $locations = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, `areaId` AS ARRAY_KEY2, `areaId` FROM ?_spawns WHERE `type` = ?d AND `typeId` IN (?a) GROUP BY `typeId`, `areaId`', Type::NPC, array_column($petList, 'id')); + $locations = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, `areaId` AS ARRAY_KEY2, `areaId` FROM ::spawns WHERE `type` = %i AND `typeId` IN %in GROUP BY `typeId`, `areaId`', Type::NPC, array_column($petList, 'id')); foreach (CLISetup::$locales as $loc) { diff --git a/setup/tools/filegen/profiler.ss.php b/setup/tools/filegen/profiler.ss.php index 8a60c3dd..b653f22b 100644 --- a/setup/tools/filegen/profiler.ss.php +++ b/setup/tools/filegen/profiler.ss.php @@ -56,7 +56,7 @@ CLISetup::registerSetup("build", new class extends SetupScript $questorder = []; $questtotal = []; $condition = [ - 'AND', + DB::AND, [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW | CUSTOM_UNAVAILABLE | CUSTOM_DISABLED, '&'], 0], [['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY | QUEST_FLAG_TRACKING, '&'], 0], [['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_DUNGEON_FINDER | QUEST_FLAG_SPECIAL_MONTHLY, '&'], 0] @@ -162,7 +162,7 @@ CLISetup::registerSetup("build", new class extends SetupScript ); $mountz = new SpellList($condition); - $conditionSet = DB::World()->selectCol('SELECT `SourceEntry` AS ARRAY_KEY, `ConditionValue1` FROM conditions WHERE `SourceTypeOrReferenceId` = ?d AND `ConditionTypeOrReference` = ?d AND `SourceEntry` IN (?a)', Conditions::SRC_SPELL, Conditions::SKILL, $mountz->getFoundIDs()); + $conditionSet = DB::World()->selectCol('SELECT `SourceEntry` AS ARRAY_KEY, `ConditionValue1` FROM conditions WHERE `SourceTypeOrReferenceId` = %i AND `ConditionTypeOrReference` = %i AND `SourceEntry` IN %in', Conditions::SRC_SPELL, Conditions::SKILL, $mountz->getFoundIDs()); // get mounts for exclusion foreach ($conditionSet as $mount => $skill) @@ -208,7 +208,7 @@ CLISetup::registerSetup("build", new class extends SetupScript ['typeCat', -6] ); $companionz = new SpellList($condition); - $legit = DB::Aowow()->selectCol('SELECT `spellId2` FROM ?_items WHERE `class` = ?d AND `subClass` = ?d AND `spellId1` IN (?a) AND `spellId2` IN (?a)', ITEM_CLASS_MISC, 2, LEARN_SPELLS, $companionz->getFoundIDs()); + $legit = DB::Aowow()->selectCol('SELECT `spellId2` FROM ::items WHERE `class` = %i AND `subClass` = %i AND `spellId1` IN %in AND `spellId2` IN %in', ITEM_CLASS_MISC, 2, LEARN_SPELLS, $companionz->getFoundIDs()); foreach ($companionz->iterate() as $id => $_) if (!$companionz->getSources()) @@ -273,7 +273,7 @@ CLISetup::registerSetup("build", new class extends SetupScript ['effect1Id', [SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_TRADE_SKILL, SPELL_EFFECT_PROSPECTING, SPELL_EFFECT_OPEN_LOCK, SPELL_EFFECT_MILLING, SPELL_EFFECT_DISENCHANT, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SKINNING], '!'], // not the skill itself ['effect2Id', [SPELL_EFFECT_SKILL, SPELL_EFFECT_PROFICIENCY], '!'], - ['OR', ['typeCat', 9], ['typeCat', 11]] + [DB::OR, ['typeCat', 9], ['typeCat', 11]] ); foreach ($skills as $s) @@ -362,15 +362,15 @@ CLISetup::registerSetup("build", new class extends SetupScript set_time_limit(2); CLI::write('[profiler] applying '.count($this->exclusions).' baseline exclusions'); - DB::Aowow()->query('DELETE FROM ?_profiler_excludes WHERE `comment` = ""'); + DB::Aowow()->qry('DELETE FROM ::profiler_excludes WHERE `comment` = ""'); foreach ($this->exclusions as $ex) - DB::Aowow()->query('REPLACE INTO ?_profiler_excludes (?#) VALUES (?a)', array_keys($ex), array_values($ex)); + DB::Aowow()->qry('REPLACE INTO ::profiler_excludes %v', $ex); // excludes; type => [excludeGroupBit => [typeIds]] $excludes = []; - $exData = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, `typeId` AS ARRAY_KEY2, `groups` FROM ?_profiler_excludes'); + $exData = DB::Aowow()->selectCol('SELECT `type` AS ARRAY_KEY, `typeId` AS ARRAY_KEY2, `groups` FROM ::profiler_excludes'); for ($i = 0; (1 << $i) < PR_EXCLUDE_GROUP_ANY; $i++) foreach ($exData as $type => $data) if ($ids = array_keys(array_filter($data, fn($x) => $x & (1 << $i)))) diff --git a/setup/tools/filegen/simpleimg.ss.php b/setup/tools/filegen/simpleimg.ss.php index ef22fe1e..6e30aedb 100644 --- a/setup/tools/filegen/simpleimg.ss.php +++ b/setup/tools/filegen/simpleimg.ss.php @@ -372,7 +372,7 @@ CLISetup::registerSetup("build", new class extends SetupScript return $m ? $m[1] : null; }, $missing); - DB::Aowow()->query('UPDATE ?_icons SET `cuFlags` = `cuFlags` | ?d WHERE `name` IN (?a)', CUSTOM_EXCLUDE_FOR_LISTVIEW, $iconNames); + DB::Aowow()->qry('UPDATE ::icons SET `cuFlags` = `cuFlags` | %i WHERE `name` IN %in', CUSTOM_EXCLUDE_FOR_LISTVIEW, $iconNames); CLI::write('[simpleimg] the following '.count($missing).' images where referenced by DBC but not in the mpqData directory. They may need to be converted by hand later on.', CLI::LOG_WARN); foreach ($missing as $m) diff --git a/setup/tools/filegen/soundfiles.ss.php b/setup/tools/filegen/soundfiles.ss.php index 10d63834..36ea6b4e 100644 --- a/setup/tools/filegen/soundfiles.ss.php +++ b/setup/tools/filegen/soundfiles.ss.php @@ -21,7 +21,7 @@ CLISetup::registerSetup("build", new class extends SetupScript public function generate() : bool { // ALL files - $files = DB::Aowow()->selectCol('SELECT ABS(`id`) AS ARRAY_KEY, CONCAT(`path`, "/", `file`) FROM ?_sounds_files'); + $files = DB::Aowow()->selectCol('SELECT ABS(`id`) AS ARRAY_KEY, CONCAT(`path`, "/", `file`) FROM ::sounds_files'); $nFiles = count($files); $qtLen = strlen($nFiles); $sum = 0; @@ -63,7 +63,7 @@ CLISetup::registerSetup("build", new class extends SetupScript CLI::write('[soundfiles] - did not find file: '.CLI::bold(CLI::nicePath($filePath, CLISetup::$srcDir, '['.implode(',', array_map(fn($x) => $x->json(), CLISetup::$locales)).']')), CLI::LOG_WARN); $time->reset(); // flag as unusable in DB - DB::Aowow()->query('UPDATE ?_sounds_files SET `id` = ?d WHERE ABS(`id`) = ?d', -$fileId, $fileId); + DB::Aowow()->qry('UPDATE ::sounds_files SET `id` = %i WHERE ABS(`id`) = %i', -$fileId, $fileId); } return $this->success; diff --git a/setup/tools/filegen/statistics.ss.php b/setup/tools/filegen/statistics.ss.php index 1f33db72..3b0afb13 100644 --- a/setup/tools/filegen/statistics.ss.php +++ b/setup/tools/filegen/statistics.ss.php @@ -73,7 +73,7 @@ CLISetup::registerSetup("build", new class extends SetupScript ); foreach ($dataz as $class => &$data) - $data[2] = array_values(DB::Aowow()->selectRow('SELECT mle.chance*100 cMle, spl.chance*100 cSpl FROM dbc_gtchancetomeleecritbase mle, dbc_gtchancetospellcritbase spl WHERE mle.idx = spl.idx AND mle.idx = ?d', $class - 1)); + $data[2] = array_values(DB::Aowow()->selectRow('SELECT mle.chance*100 cMle, spl.chance*100 cSpl FROM dbc_gtchancetomeleecritbase mle, dbc_gtchancetospellcritbase spl WHERE mle.idx = spl.idx AND mle.idx = %i', $class - 1)); return $dataz; } @@ -81,7 +81,7 @@ CLISetup::registerSetup("build", new class extends SetupScript // { str, agi, sta, int, spi, raceMod1, raceMod2 } private function race() : array { - $raceData = DB::World()->select('SELECT `race` AS ARRAY_KEY, MIN(`str`), MIN(`agi`), MIN(`sta`), MIN(`inte`), MIN(`spi`) FROM player_levelstats WHERE `level` = 1 GROUP BY `race` ORDER BY `race` ASC'); + $raceData = DB::World()->selectAssoc('SELECT `race` AS ARRAY_KEY, MIN(`str`), MIN(`agi`), MIN(`sta`), MIN(`inte`), MIN(`spi`) FROM player_levelstats WHERE `level` = 1 GROUP BY `race` ORDER BY `race` ASC'); foreach ($raceData as &$rd) $rd = array_values($rd + [[], []]); @@ -130,27 +130,27 @@ CLISetup::registerSetup("build", new class extends SetupScript else $offset = array_values(DB::World()->selectRow('SELECT MIN(`str`), MIN(`agi`), MIN(`sta`), MIN(`inte`), MIN(`spi`) FROM player_levelstats WHERE `level` = 1 AND `race` = 1')); - $gtData = DB::Aowow()->select( - 'SELECT mlecrt.idx - ?d AS ARRAY_KEY, mlecrt.chance * 100, splcrt.chance * 100, mlecrt.chance * 100 * ?f, baseHP5.ratio * 1, extraHP5.ratio * 1 + $gtData = DB::Aowow()->selectAssoc( + 'SELECT mlecrt.idx - %i AS ARRAY_KEY, mlecrt.chance * 100, splcrt.chance * 100, mlecrt.chance * 100 * %f, baseHP5.ratio * 1, extraHP5.ratio * 1 FROM dbc_gtchancetomeleecrit mlecrt JOIN dbc_gtchancetospellcrit splcrt ON splcrt.idx = mlecrt.idx JOIN dbc_gtoctregenhp baseHP5 ON baseHP5.idx = mlecrt.idx JOIN dbc_gtregenhpperspt extraHP5 ON extraHP5.idx = mlecrt.idx - WHERE mlecrt.idx BETWEEN ?d AND ?d', + WHERE mlecrt.idx BETWEEN %i AND %i', (($class - 1) * 100) - 1, // class-offset $mod, (($class - 1) * 100) + 0, // lvl 1 (($class - 1) * 100) + 79 // lvl 80 ); - $rows = DB::World()->select( + $rows = DB::World()->selectAssoc( 'SELECT pls.level AS ARRAY_KEY, - pls.str - ?d, pls.agi - ?d, pls.sta - ?d, pls.inte - ?d, pls.spi - ?d, + pls.str - %i, pls.agi - %i, pls.sta - %i, pls.inte - %i, pls.spi - %i, pcls.basehp, IF(pcls.basemana <> 0, pcls.basemana, 100) FROM player_levelstats pls JOIN player_classlevelstats pcls ON pls.level = pcls.level AND pls.class = pcls.class - WHERE pls.race = ?d AND - pls.class = ?d + WHERE pls.race = %i AND + pls.class = %i ORDER BY pls.level ASC', $offset[0], $offset[1], $offset[2], $offset[3], $offset[4], in_array($class, [3, 7, 11]) ? 6 : 1, @@ -170,13 +170,13 @@ CLISetup::registerSetup("build", new class extends SetupScript // content of gtRegenMPPerSpt.dbc private function level() : array { - return DB::Aowow()->selectCol('SELECT idx-99 AS ARRAY_KEY, ratio FROM dbc_gtregenmpperspt WHERE idx >= 100 AND idx < 100 + ?d', MAX_LEVEL); + return DB::Aowow()->selectCol('SELECT idx-99 AS ARRAY_KEY, ratio FROM dbc_gtregenmpperspt WHERE idx >= 100 AND idx < 100 + %i', MAX_LEVEL); } // profession perks ... too lazy to formulate a search algorithm for two occurences private function skills() : array { - // DB::Aowow()->select( + // DB::Aowow()->selectAssoc( // 'SELECT sk.id AS "skillId", sla.reqSkillLevel, s.effect1AuraId AS "auraId", s.effect1MiscValue, s.effect1BasePoints + s.effect1DieSides AS "qty" // FROM dbc_skilllineability sla // JOIN dbc_skillline sk ON sk.id = sla.skilllineid diff --git a/setup/tools/filegen/talentcalc.ss.php b/setup/tools/filegen/talentcalc.ss.php index cb43833f..1207fdf4 100644 --- a/setup/tools/filegen/talentcalc.ss.php +++ b/setup/tools/filegen/talentcalc.ss.php @@ -51,7 +51,7 @@ CLISetup::registerSetup("build", new class extends SetupScript $this->petFamIcons = ['Ability_Druid_KingoftheJungle', 'Ability_Druid_DemoralizingRoar', 'Ability_EyeOfTheOwl']; // .. i've no idea where to fetch these from $this->spellMods = (new SpellList(array(['typeCat', -2])))->getProfilerMods(); - $petIcons = Util::toJSON(DB::Aowow()->SelectCol('SELECT `id` AS ARRAY_KEY, LOWER(SUBSTRING_INDEX(`iconString`, "\\\\", -1)) AS "iconString" FROM dbc_creaturefamily WHERE `petTalentType` IN (0, 1, 2)')); + $petIcons = Util::toJSON(DB::Aowow()->SelectCol('SELECT `id` AS ARRAY_KEY, LOWER(SUBSTRING_INDEX(`iconString`, "\\", -1)) AS "iconString" FROM dbc_creaturefamily WHERE `petTalentType` IN (0, 1, 2)')); $tSpellIds = DB::Aowow()->selectCol('SELECT `rank1` FROM dbc_talent UNION SELECT `rank2` FROM dbc_talent UNION SELECT `rank3` FROM dbc_talent UNION SELECT `rank4` FROM dbc_talent UNION SELECT `rank5` FROM dbc_talent'); $this->tSpells = new SpellList(array(['s.id', $tSpellIds])); @@ -89,17 +89,17 @@ CLISetup::registerSetup("build", new class extends SetupScript $petCategories = []; // All "tabs" of a given class talent - $tabs = DB::Aowow()->select('SELECT * FROM dbc_talenttab WHERE `classMask` = ?d ORDER BY `tabNumber`, `creatureFamilyMask`', $classMask); + $tabs = DB::Aowow()->selectAssoc('SELECT * FROM dbc_talenttab WHERE `classMask` = %i ORDER BY `tabNumber`, `creatureFamilyMask`', $classMask); $result = []; for ($tabIdx = 0; $tabIdx < count($tabs); $tabIdx++) { - $talents = DB::Aowow()->select( + $talents = DB::Aowow()->selectAssoc( 'SELECT t.id AS "tId", t.*, IF(t.rank5, 5, IF(t.rank4, 4, IF(t.rank3, 3, IF(t.rank2, 2, 1)))) AS "maxRank", s.`name_loc0`, s.`name_loc2`, s.`name_loc3`, s.`name_loc4`, s.`name_loc6`, s.`name_loc8`, - LOWER(SUBSTRING_INDEX(si.`iconPath`, "\\\\", -1)) AS "iconString" + LOWER(SUBSTRING_INDEX(si.`iconPath`, "\\", -1)) AS "iconString" FROM dbc_talent t, dbc_spell s, dbc_spellicon si - WHERE si.`id` = s.`iconId` AND t.`tabId`= ?d AND s.`id` = t.`rank1` + WHERE si.`id` = s.`iconId` AND t.`tabId`= %i AND s.`id` = t.`rank1` ORDER BY t.`row`, t.`column`, t.`id` ASC', $tabs[$tabIdx]['id'] ); @@ -113,7 +113,7 @@ CLISetup::registerSetup("build", new class extends SetupScript { $petFamId = log($tabs[$tabIdx]['creatureFamilyMask'], 2); $result[$tabIdx]['icon'] = $this->petFamIcons[$petFamId]; - $petCategories = DB::Aowow()->SelectCol('SELECT `id` AS ARRAY_KEY, `categoryEnumID` FROM dbc_creaturefamily WHERE `petTalentType` = ?d', $petFamId); + $petCategories = DB::Aowow()->SelectCol('SELECT `id` AS ARRAY_KEY, `categoryEnumID` FROM dbc_creaturefamily WHERE `petTalentType` = %i', $petFamId); $result[$tabIdx]['f'] = array_keys($petCategories); } diff --git a/setup/tools/filegen/talenticons.ss.php b/setup/tools/filegen/talenticons.ss.php index cde3143f..efbdfdbe 100644 --- a/setup/tools/filegen/talenticons.ss.php +++ b/setup/tools/filegen/talenticons.ss.php @@ -79,12 +79,12 @@ CLISetup::registerSetup("build", new class extends SetupScript private function compileTexture(string $ttField, int $searchMask, int $tabIdx) : ?\GdImage { $icons = DB::Aowow()->SelectCol( - 'SELECT ic.`name` AS "iconString" - FROM ?_icons ic - JOIN ?_spell s ON s.`iconId` = ic.`id` + 'SELECT ic.`name` + FROM ::icons ic + JOIN ::spell s ON s.`iconId` = ic.`id` JOIN dbc_talent t ON t.`rank1` = s.`id` JOIN dbc_talenttab tt ON tt.`id` = t.`tabId` - WHERE tt.?# = ?d AND tt.`tabNumber` = ?d + WHERE tt.%n = %i AND tt.`tabNumber` = %i ORDER BY t.`row`, t.`column`, t.`id` ASC', $ttField, $searchMask, $tabIdx); diff --git a/setup/tools/filegen/weightpresets.ss.php b/setup/tools/filegen/weightpresets.ss.php index e884fa2f..00569920 100644 --- a/setup/tools/filegen/weightpresets.ss.php +++ b/setup/tools/filegen/weightpresets.ss.php @@ -21,11 +21,11 @@ CLISetup::registerSetup("build", new class extends SetupScript public function generate() : bool { $wtPresets = []; - $scales = DB::Aowow()->select('SELECT `id`, `name`, `icon`, `class` FROM ?_account_weightscales WHERE `userId` = 0 ORDER BY `class`, `orderIdx` ASC'); + $scales = DB::Aowow()->selectAssoc('SELECT `id`, `name`, `icon`, `class` FROM ::account_weightscales WHERE `userId` = 0 ORDER BY `class`, `orderIdx` ASC'); foreach ($scales as $s) { - if ($weights = DB::Aowow()->selectCol('SELECT `field` AS ARRAY_KEY, `val` FROM ?_account_weightscale_data WHERE `id` = ?d', $s['id'])) + if ($weights = DB::Aowow()->selectCol('SELECT `field` AS ARRAY_KEY, `val` FROM ::account_weightscale_data WHERE `id` = %i', $s['id'])) $wtPresets[$s['class']]['pve'][$s['name']] = array_merge(['__icon' => $s['icon']], $weights); else { diff --git a/setup/tools/setupScript.class.php b/setup/tools/setupScript.class.php index 7ad40a84..608c80e1 100644 --- a/setup/tools/setupScript.class.php +++ b/setup/tools/setupScript.class.php @@ -44,11 +44,11 @@ trait TrCustomData public function applyCustomData() : bool { $ok = true; - foreach ((DB::Aowow()->selectCol('SELECT `entry` AS ARRAY_KEY, `field` AS ARRAY_KEY2, `value` FROM ?_setup_custom_data WHERE `command` = ?', $this->getName()) ?: []) as $id => $data) + foreach ((DB::Aowow()->selectCol('SELECT `entry` AS ARRAY_KEY, `field` AS ARRAY_KEY2, `value` FROM ::setup_custom_data WHERE `command` = %s', $this->getName()) ?: []) as $id => $data) { try { - DB::Aowow()->query('UPDATE ?_'.$this->getName().' SET ?a WHERE id = ?d', $data, $id); + DB::Aowow()->qry('UPDATE %n SET %a WHERE id = %i', '::'.$this->getName(), $data, $id); } catch (\Exception $e) { @@ -602,9 +602,9 @@ abstract class SetupScript return; } - DB::Aowow()->query('UPDATE ?_'.$tbl.' x, ?_comments y SET x.`cuFlags` = x.`cuFlags` | ?d WHERE x.`id` = y.`typeId` AND y.`type` = ?d AND y.`flags` & ?d', CUSTOM_HAS_COMMENT, $type, CC_FLAG_APPROVED); - DB::Aowow()->query('UPDATE ?_'.$tbl.' x, ?_screenshots y SET x.`cuFlags` = x.`cuFlags` | ?d WHERE x.`id` = y.`typeId` AND y.`type` = ?d AND y.`status` & ?d', CUSTOM_HAS_SCREENSHOT, $type, CC_FLAG_APPROVED); - DB::Aowow()->query('UPDATE ?_'.$tbl.' x, ?_videos y SET x.`cuFlags` = x.`cuFlags` | ?d WHERE x.`id` = y.`typeId` AND y.`type` = ?d AND y.`status` & ?d', CUSTOM_HAS_VIDEO, $type, CC_FLAG_APPROVED); + DB::Aowow()->qry('UPDATE ::'.$tbl.' x, ::comments y SET x.`cuFlags` = x.`cuFlags` | %i WHERE x.`id` = y.`typeId` AND y.`type` = %i AND y.`flags` & %i', CUSTOM_HAS_COMMENT, $type, CC_FLAG_APPROVED); + DB::Aowow()->qry('UPDATE ::'.$tbl.' x, ::screenshots y SET x.`cuFlags` = x.`cuFlags` | %i WHERE x.`id` = y.`typeId` AND y.`type` = %i AND y.`status` & %i', CUSTOM_HAS_SCREENSHOT, $type, CC_FLAG_APPROVED); + DB::Aowow()->qry('UPDATE ::'.$tbl.' x, ::videos y SET x.`cuFlags` = x.`cuFlags` | %i WHERE x.`id` = y.`typeId` AND y.`type` = %i AND y.`status` & %i', CUSTOM_HAS_VIDEO, $type, CC_FLAG_APPROVED); } } diff --git a/setup/tools/sqlgen/achievement.ss.php b/setup/tools/sqlgen/achievement.ss.php index 067229ba..f68bb490 100644 --- a/setup/tools/sqlgen/achievement.ss.php +++ b/setup/tools/sqlgen/achievement.ss.php @@ -21,10 +21,10 @@ CLISetup::registerSetup('sql', new class extends SetupScript protected $worldDependency = ['dbc_achievement', 'disables']; protected $setupAfter = [['icons'], []]; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_achievement'); - DB::Aowow()->query('TRUNCATE ?_achievementcategory'); + DB::Aowow()->qry('TRUNCATE ::achievement'); + DB::Aowow()->qry('TRUNCATE ::achievementcategory'); /**************/ /* categories */ @@ -32,7 +32,7 @@ CLISetup::registerSetup('sql', new class extends SetupScript CLI::write('[achievement] - resolving categories'); - DB::Aowow()->query('INSERT INTO ?_achievementcategory SELECT ac.id, GREATEST(ac.parentcategory, 0), GREATEST(IFNULL(ac1.parentcategory, 0), 0) FROM dbc_achievement_category ac LEFT JOIN dbc_achievement_category ac1 ON ac1.id = ac.parentCategory'); + DB::Aowow()->qry('INSERT INTO ::achievementcategory SELECT ac.id, GREATEST(ac.parentcategory, 0), GREATEST(IFNULL(ac1.parentcategory, 0), 0) FROM dbc_achievement_category ac LEFT JOIN dbc_achievement_category ac1 ON ac1.id = ac.parentCategory'); /************/ /* dbc data */ @@ -40,8 +40,8 @@ CLISetup::registerSetup('sql', new class extends SetupScript CLI::write('[achievement] - basic dbc data'); - DB::Aowow()->query( - 'INSERT INTO ?_achievement + DB::Aowow()->qry( + 'INSERT INTO ::achievement SELECT a.id, 2 - a.faction, a.map, @@ -64,9 +64,7 @@ CLISetup::registerSetup('sql', new class extends SetupScript FROM dbc_achievement a LEFT JOIN dbc_achievement_category ac ON ac.id = a.category LEFT JOIN dbc_spellicon si ON si.id = a.iconId - LEFT JOIN ?_icons i ON LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1)) = i.name_source - { WHERE a.id IN (?a) }', - $ids ?: DBSIMPLE_SKIP + LEFT JOIN ::icons i ON LOWER(SUBSTRING_INDEX(si.iconPath, "\\", -1)) = i.name_source', ); @@ -76,9 +74,7 @@ CLISetup::registerSetup('sql', new class extends SetupScript CLI::write('[achievement] - serverside achievement data'); - $serverAchievements = DB::World()->select('SELECT `ID` AS "id", IF(`requiredFaction` = -1, 3, IF(`requiredFaction` = 0, 2, 1)) AS "faction", `mapID` AS "map", `points`, `flags`, `count` AS "reqCriteriaCount", `refAchievement` FROM achievement_dbc{ WHERE `id` IN (?a)}', - $ids ?: DBSIMPLE_SKIP - ); + $serverAchievements = DB::World()->selectAssoc('SELECT `ID` AS "id", IF(`requiredFaction` = -1, 3, IF(`requiredFaction` = 0, 2, 1)) AS "faction", `mapID` AS "map", `points`, `flags`, `count` AS "reqCriteriaCount", `refAchievement` FROM achievement_dbc'); foreach ($serverAchievements as &$sa) { @@ -91,7 +87,7 @@ CLISetup::registerSetup('sql', new class extends SetupScript unset($sa); foreach ($serverAchievements as $sa) - DB::Aowow()->query('INSERT INTO ?_achievement (?#) VALUES (?a)', array_keys($sa), array_values($sa)); + DB::Aowow()->qry('INSERT INTO ::achievement %v', $sa); /********************************/ @@ -104,7 +100,7 @@ CLISetup::registerSetup('sql', new class extends SetupScript foreach ($parents as $chainId => $next) { $tree = [null, $next]; - while ($next = DB::Aowow()->selectCell('SELECT `id` FROM dbc_achievement WHERE `previous` = ?d', $next)) + while ($next = DB::Aowow()->selectCell('SELECT `id` FROM dbc_achievement WHERE `previous` = %i', $next)) $tree[] = $next; foreach ($tree as $idx => $aId) @@ -112,7 +108,7 @@ CLISetup::registerSetup('sql', new class extends SetupScript if (!$aId) continue; - DB::Aowow()->query('UPDATE ?_achievement SET `cuFlags` = `cuFlags` | ?d, `chainId` = ?d, `chainPos` = ?d WHERE `id` = ?d', + DB::Aowow()->qry('UPDATE ::achievement SET `cuFlags` = `cuFlags` | %i, `chainId` = %i, `chainPos` = %i WHERE `id` = %i', $idx == 1 ? ACHIEVEMENT_CU_FIRST_SERIES : (count($tree) == $idx + 1 ? ACHIEVEMENT_CU_LAST_SERIES : 0), $chainId + 1, $idx, @@ -129,7 +125,7 @@ CLISetup::registerSetup('sql', new class extends SetupScript CLI::write('[achievement] - disabling disabled achievements from table disables'); if ($criteria = DB::World()->selectCol('SELECT `entry` FROM disables WHERE `sourceType` = 4')) - DB::Aowow()->query('UPDATE ?_achievement a JOIN ?_achievementcriteria ac ON a.`id` = ac.`refAchievementId` SET a.`cuFlags` = ?d WHERE ac.`id` IN (?a)', CUSTOM_DISABLED, $criteria); + DB::Aowow()->qry('UPDATE ::achievement a JOIN ::achievementcriteria ac ON a.`id` = ac.`refAchievementId` SET a.`cuFlags` = %i WHERE ac.`id` IN %in', CUSTOM_DISABLED, $criteria); $this->reapplyCCFlags('achievement', Type::ACHIEVEMENT); diff --git a/setup/tools/sqlgen/areatrigger.ss.php b/setup/tools/sqlgen/areatrigger.ss.php index 02c36d8b..8d775e76 100644 --- a/setup/tools/sqlgen/areatrigger.ss.php +++ b/setup/tools/sqlgen/areatrigger.ss.php @@ -18,10 +18,10 @@ CLISetup::registerSetup('sql', new class extends SetupScript protected $dbcSourceFiles = ['areatrigger']; protected $worldDependency = ['areatrigger_involvedrelation', 'areatrigger_scripts', 'areatrigger_tavern', 'areatrigger_teleport', 'quest_template', 'quest_template_addon']; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_areatrigger'); - DB::Aowow()->query('INSERT INTO ?_areatrigger SELECT `id`, 0, 0, `mapId`, `posX`, `posY`, `orientation`, NULL, NULL FROM dbc_areatrigger'); + DB::Aowow()->qry('TRUNCATE ::areatrigger'); + DB::Aowow()->qry('INSERT INTO ::areatrigger SELECT `id`, 0, 0, `mapId`, `posX`, `posY`, `orientation`, NULL, NULL FROM dbc_areatrigger'); /* notes: * while areatrigger DO have dimensions, displaying them on a map is almost always futile, @@ -31,42 +31,42 @@ CLISetup::registerSetup('sql', new class extends SetupScript // 1: Taverns CLI::write('[areatrigger] - fetching taverns'); - $addData = DB::World()->select('SELECT `id` AS ARRAY_KEY, `name`, ?d AS `type` FROM areatrigger_tavern', AT_TYPE_TAVERN); + $addData = DB::World()->selectAssoc('SELECT `id` AS ARRAY_KEY, `name`, %i AS `type` FROM areatrigger_tavern', AT_TYPE_TAVERN); foreach ($addData as $id => $ad) - DB::Aowow()->query('UPDATE ?_areatrigger SET ?a WHERE `id` = ?d', $ad, $id); + DB::Aowow()->qry('UPDATE ::areatrigger SET %a WHERE `id` = %i', $ad, $id); // 2: Teleporter CLI::write('[areatrigger] - teleporter type and name'); - $addData = DB::World()->select( + $addData = DB::World()->selectAssoc( 'SELECT `ID` AS ARRAY_KEY, `Name` AS `name` FROM areatrigger_teleport UNION - SELECT `entryorguid` AS ARRAY_KEY, "SAI Teleport" AS `name` FROM smart_scripts WHERE `source_type` = ?d AND `action_type` = ?d', + SELECT `entryorguid` AS ARRAY_KEY, "SAI Teleport" AS `name` FROM smart_scripts WHERE `source_type` = %i AND `action_type` = %i', SmartAI::SRC_TYPE_AREATRIGGER, SmartAction::ACTION_TELEPORT ); foreach ($addData as $id => $ad) - DB::Aowow()->query('UPDATE ?_areatrigger SET `name` = ?, `type` = ?d WHERE `id` = ?d', $ad['name'], AT_TYPE_TELEPORT, $id); + DB::Aowow()->qry('UPDATE ::areatrigger SET `name` = %s, `type` = %i WHERE `id` = %i', $ad['name'], AT_TYPE_TELEPORT, $id); // 3: Quest Objectives CLI::write('[areatrigger] - satisfying quest objectives'); - $addData = DB::World()->select('SELECT atir.`id` AS ARRAY_KEY, `qt`.ID AS `quest`, NULLIF(qt.`AreaDescription`, "") AS `name`, qta.`SpecialFlags` FROM quest_template qt LEFT JOIN quest_template_addon qta ON qta.`ID` = qt.`ID` JOIN areatrigger_involvedrelation atir ON atir.`quest` = qt.`ID`'); + $addData = DB::World()->selectAssoc('SELECT atir.`id` AS ARRAY_KEY, `qt`.ID AS `quest`, NULLIF(qt.`AreaDescription`, "") AS `name`, qta.`SpecialFlags` FROM quest_template qt LEFT JOIN quest_template_addon qta ON qta.`ID` = qt.`ID` JOIN areatrigger_involvedrelation atir ON atir.`quest` = qt.`ID`'); foreach ($addData as $id => $ad) { if (!($ad['SpecialFlags'] & QUEST_FLAG_SPECIAL_EXT_COMPLETE)) CLI::write('[areatrigger] '.str_pad('['.$id.']', 8).' is involved in quest '.CLI::bold($ad['quest']).', but quest is not flagged for external completion (SpecialFlags & '.Util::asHex(QUEST_FLAG_SPECIAL_EXT_COMPLETE).')', CLI::LOG_WARN); - DB::Aowow()->query('UPDATE ?_areatrigger SET `name` = ?, type = ?d, `quest` = ?d WHERE `id` = ?d', $ad['name'], AT_TYPE_OBJECTIVE, $ad['quest'], $id); + DB::Aowow()->qry('UPDATE ::areatrigger SET `name` = %s, type = %i, `quest` = %i WHERE `id` = %i', $ad['name'], AT_TYPE_OBJECTIVE, $ad['quest'], $id); } // 4/5 Scripted CLI::write('[areatrigger] - assigning scripts'); - $addData = DB::World()->select('SELECT `entry` AS ARRAY_KEY, IF(`ScriptName` = "SmartTrigger", NULL, `ScriptName`) AS `name`, IF(`ScriptName` = "SmartTrigger", 4, 5) AS `type` FROM areatrigger_scripts'); + $addData = DB::World()->selectAssoc('SELECT `entry` AS ARRAY_KEY, IF(`ScriptName` = "SmartTrigger", NULL, `ScriptName`) AS `name`, IF(`ScriptName` = "SmartTrigger", 4, 5) AS `type` FROM areatrigger_scripts'); foreach ($addData as $id => $ad) - DB::Aowow()->query('UPDATE ?_areatrigger SET ?a WHERE `id` = ?d', $ad, $id); + DB::Aowow()->qry('UPDATE ::areatrigger SET %a WHERE `id` = %i', $ad, $id); $this->reapplyCCFlags('areatrigger', Type::AREATRIGGER); diff --git a/setup/tools/sqlgen/classes.ss.php b/setup/tools/sqlgen/classes.ss.php index 661efccc..f972ac20 100644 --- a/setup/tools/sqlgen/classes.ss.php +++ b/setup/tools/sqlgen/classes.ss.php @@ -20,23 +20,23 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $setupAfter = [['icons'], []]; protected $dbcSourceFiles = ['spell', 'charbaseinfo', 'skillraceclassinfo', 'skilllineability', 'chrclasses']; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_classes'); + DB::Aowow()->qry('TRUNCATE ::classes'); - $classes = DB::Aowow()->select('SELECT *, `id` AS ARRAY_KEY FROM dbc_chrclasses'); + $classes = DB::Aowow()->selectAssoc('SELECT *, `id` AS ARRAY_KEY FROM dbc_chrclasses'); // add raceMask - $races = DB::Aowow()->select('SELECT `classId` AS ARRAY_KEY, BIT_OR(1 << (`raceId` - 1)) AS "raceMask" FROM dbc_charbaseinfo GROUP BY `classId`'); + $races = DB::Aowow()->selectAssoc('SELECT `classId` AS ARRAY_KEY, BIT_OR(1 << (`raceId` - 1)) AS "raceMask" FROM dbc_charbaseinfo GROUP BY `classId`'); Util::arraySumByKey($classes, $races); // add skills - if ($skills = DB::Aowow()->selectCol('SELECT LOG(2, `classMask`) + 1 AS ARRAY_KEY, GROUP_CONCAT(`skillLine` SEPARATOR \' \') FROM dbc_skillraceclassinfo WHERE `flags` = ?d GROUP BY `classMask` HAVING ARRAY_KEY = CAST(LOG(2, `classMask`) + 1 AS SIGNED)', 0x410)) + if ($skills = DB::Aowow()->selectCol('SELECT LOG(2, `classMask`) + 1 AS ARRAY_KEY, GROUP_CONCAT(`skillLine` SEPARATOR \' \') FROM dbc_skillraceclassinfo WHERE `flags` = %i GROUP BY `classMask` HAVING ARRAY_KEY = CAST(LOG(2, `classMask`) + 1 AS SIGNED)', 0x410)) foreach ($skills as $classId => $skillStr) $classes[$classId]['skills'] = $skillStr; // collect iconIds - $iconIds = DB::Aowow()->selectCol('SELECT `id`, `name` AS ARRAY_KEY FROM ?_icons WHERE `name` IN (?a)', array_filter(array_map(fn($x) => 'class_'.strtolower($x['fileString']), $classes))); + $iconIds = DB::Aowow()->selectCol('SELECT `id`, `name` AS ARRAY_KEY FROM ::icons WHERE `name` IN %in', array_filter(array_map(fn($x) => 'class_'.strtolower($x['fileString']), $classes))); foreach ($classes AS $id => $class) $classes[$id]['iconId'] = $iconIds['class_'.strtolower($class['fileString'])] ?? 0; @@ -48,22 +48,22 @@ CLISetup::registerSetup("sql", new class extends SetupScript 'SELECT BIT_OR(`equippedItemSubClassMask`) FROM dbc_spell s JOIN dbc_skilllineability sla ON sla.`spellId` = s.`id` - JOIN dbc_skillraceclassinfo srci ON srci.`skillLine` = sla.`skillLineId` AND srci.`classMask` & ?d - WHERE sla.`skilllineid` <> 183 AND (sla.`reqClassMask` & ?d OR sla.`reqClassMask` = 0) AND `equippedItemClass` = ?d AND (`effect1Id` = ?d OR `effect2Id` = ?d)', + JOIN dbc_skillraceclassinfo srci ON srci.`skillLine` = sla.`skillLineId` AND srci.`classMask` & %i + WHERE sla.`skilllineid` <> 183 AND (sla.`reqClassMask` & %i OR sla.`reqClassMask` = 0) AND `equippedItemClass` = %i AND (`effect1Id` = %i OR `effect2Id` = %i)', $mask, $mask, ITEM_CLASS_WEAPON, SPELL_EFFECT_PROFICIENCY, SPELL_EFFECT_PROFICIENCY ); $data['armorTypeMask'] = DB::Aowow()->selectCell( 'SELECT BIT_OR(`equippedItemSubClassMask`) FROM dbc_spell s JOIN dbc_skilllineability sla ON sla.`spellId` = s.`id` - JOIN dbc_skillraceclassinfo srci ON srci.`skillLine` = sla.`skillLineId` AND srci.`classMask` & ?d - WHERE sla.`reqClassMask` & ?d AND `equippedItemClass` = ?d AND (`effect1Id` = ?d OR `effect2Id` = ?d)', + JOIN dbc_skillraceclassinfo srci ON srci.`skillLine` = sla.`skillLineId` AND srci.`classMask` & %i + WHERE sla.`reqClassMask` & %i AND `equippedItemClass` = %i AND (`effect1Id` = %i OR `effect2Id` = %i)', $mask, $mask, ITEM_CLASS_ARMOR, SPELL_EFFECT_PROFICIENCY, SPELL_EFFECT_PROFICIENCY ); } foreach ($classes as $cl) - DB::Aowow()->query('INSERT INTO ?_classes (?#) VALUES (?a)', array_keys($cl), array_values($cl)); + DB::Aowow()->qry('INSERT INTO ::classes %v', $cl); $this->reapplyCCFlags('classes', Type::CHR_CLASS); diff --git a/setup/tools/sqlgen/creature.ss.php b/setup/tools/sqlgen/creature.ss.php index 9691b5a0..0a90edd5 100644 --- a/setup/tools/sqlgen/creature.ss.php +++ b/setup/tools/sqlgen/creature.ss.php @@ -18,11 +18,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['creaturedisplayinfo', 'creaturedisplayinfoextra']; protected $worldDependency = ['creature_template', 'creature_template_locale', 'creature_template_resistance', 'creature_template_spell', 'creature_classlevelstats', 'creature_default_trainer', 'trainer', 'instance_encounters']; - public function generate(array $ids = []) : bool + public function generate() : bool { $baseQuery = 'SELECT ct.entry, - IF(ie.creditEntry IS NULL, 0, ?d) AS cuFlags, + IF(ie.creditEntry IS NULL, 0, %i) AS cuFlags, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, @@ -99,24 +99,23 @@ CLISetup::registerSetup("sql", new class extends SetupScript LEFT JOIN creature_template_resistance ctr4 ON ct.entry = ctr4.CreatureID AND ctr4.School = 4 LEFT JOIN creature_template_resistance ctr5 ON ct.entry = ctr5.CreatureID AND ctr5.School = 5 LEFT JOIN creature_template_resistance ctr6 ON ct.entry = ctr6.CreatureID AND ctr6.School = 6 - { WHERE ct.entry IN (?a) } - LIMIT ?d, ?d'; + LIMIT %i, %i'; - DB::Aowow()->query('TRUNCATE ?_creature'); - DB::Aowow()->query('SET SESSION innodb_ft_enable_stopword = OFF'); + DB::Aowow()->qry('TRUNCATE ::creature'); + DB::Aowow()->qry('SET SESSION innodb_ft_enable_stopword = OFF'); $i = 0; - while ($npcs = DB::World()->select($baseQuery, NPC_CU_INSTANCE_BOSS, $ids ?: DBSIMPLE_SKIP, CLISetup::SQL_BATCH * $i, CLISetup::SQL_BATCH)) + while ($npcs = DB::World()->selectAssoc($baseQuery, NPC_CU_INSTANCE_BOSS, CLISetup::SQL_BATCH * $i, CLISetup::SQL_BATCH)) { CLI::write(' * batch #' . ++$i . ' (' . count($npcs) . ')', CLI::LOG_BLANK, true, true); foreach ($npcs as $npc) - DB::Aowow()->query('INSERT INTO ?_creature VALUES (?a)', array_values($npc)); + DB::Aowow()->qry('INSERT INTO ::creature VALUES %l', $npc); } // apply "textureString", "modelId" and "iconSring" - DB::Aowow()->query( - 'UPDATE ?_creature c + DB::Aowow()->qry( + 'UPDATE ::creature c JOIN dbc_creaturedisplayinfo cdi ON c.displayId1 = cdi.id LEFT JOIN dbc_creaturedisplayinfoextra cdie ON cdi.extraInfoId = cdie.id SET c.textureString = IFNULL(cdie.textureString, cdi.skin1), @@ -126,21 +125,21 @@ CLISetup::registerSetup("sql", new class extends SetupScript ); // apply cuFlag: difficultyDummy - DB::Aowow()->query( - 'UPDATE ?_creature a - JOIN (SELECT b.difficultyEntry1 AS dummy FROM ?_creature b UNION - SELECT c.difficultyEntry2 AS dummy FROM ?_creature c UNION - SELECT d.difficultyEntry3 AS dummy FROM ?_creature d) j - SET a.cuFlags = a.cuFlags | ?d + DB::Aowow()->qry( + 'UPDATE ::creature a + JOIN (SELECT b.difficultyEntry1 AS dummy FROM ::creature b UNION + SELECT c.difficultyEntry2 AS dummy FROM ::creature c UNION + SELECT d.difficultyEntry3 AS dummy FROM ::creature d) j + SET a.cuFlags = a.cuFlags | %i WHERE a.id = j.dummy', NPC_CU_DIFFICULTY_DUMMY | CUSTOM_EXCLUDE_FOR_LISTVIEW ); // apply cuFlag: excludeFromListview [for trigger-creatures] - DB::Aowow()->query('UPDATE ?_creature SET cuFlags = cuFlags | ?d WHERE flagsExtra & ?d', CUSTOM_EXCLUDE_FOR_LISTVIEW, 0x80); + DB::Aowow()->qry('UPDATE ::creature SET cuFlags = cuFlags | %i WHERE flagsExtra & %i', CUSTOM_EXCLUDE_FOR_LISTVIEW, 0x80); // apply cuFlag: exCludeFromListview [for nameparts indicating internal usage] - DB::Aowow()->query('UPDATE ?_creature SET cuFlags = cuFlags | ?d WHERE name_loc0 LIKE "%[%" OR name_loc0 LIKE "%(%" OR name_loc0 LIKE "%visual%" OR name_loc0 LIKE "%trigger%" OR name_loc0 LIKE "%credit%" OR name_loc0 LIKE "%marker%"', CUSTOM_EXCLUDE_FOR_LISTVIEW); + DB::Aowow()->qry('UPDATE ::creature SET cuFlags = cuFlags | %i WHERE name_loc0 LIKE "%[%" OR name_loc0 LIKE "%(%" OR name_loc0 LIKE "%visual%" OR name_loc0 LIKE "%trigger%" OR name_loc0 LIKE "%credit%" OR name_loc0 LIKE "%marker%"', CUSTOM_EXCLUDE_FOR_LISTVIEW); $this->reapplyCCFlags('creature', Type::NPC); diff --git a/setup/tools/sqlgen/currencies.ss.php b/setup/tools/sqlgen/currencies.ss.php index 3db2ba45..79fcf193 100644 --- a/setup/tools/sqlgen/currencies.ss.php +++ b/setup/tools/sqlgen/currencies.ss.php @@ -21,15 +21,15 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $worldDependency = ['item_template', 'item_template_locale']; protected $setupAfter = [['icons'], []]; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_currencies'); - DB::Aowow()->query('INSERT INTO ?_currencies (`id`, `category`, `itemId`) SELECT `id`, LEAST(`category`, 41), `itemId` FROM dbc_currencytypes'); + DB::Aowow()->qry('TRUNCATE ::currencies'); + DB::Aowow()->qry('INSERT INTO ::currencies (`id`, `category`, `itemId`) SELECT `id`, LEAST(`category`, 41), `itemId` FROM dbc_currencytypes'); - $moneyItems = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `itemId` FROM dbc_currencytypes{ WHERE `id` IN (?a)}', $ids ?: DBSIMPLE_SKIP); + $moneyItems = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `itemId` FROM dbc_currencytypes'); // apply names & cap - $moneyNames = DB::World()->select( + $moneyNames = DB::World()->selectAssoc( 'SELECT it.`entry` AS ARRAY_KEY, it.`name` AS `name_loc0`, IFNULL(itl2.`Name`, "") AS `name_loc2`, IFNULL(itl3.`Name`, "") AS `name_loc3`, IFNULL(itl4.`Name`, "") AS `name_loc4`, IFNULL(itl6.`Name`, "") AS `name_loc6`, IFNULL(itl8.`Name`, "") AS `name_loc8`, it.`maxCount` AS `cap` @@ -39,7 +39,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript LEFT JOIN item_template_locale itl4 ON it.entry = itl4.ID AND itl4.locale = "zhCN" LEFT JOIN item_template_locale itl6 ON it.entry = itl6.ID AND itl6.locale = "esES" LEFT JOIN item_template_locale itl8 ON it.entry = itl8.ID AND itl8.locale = "ruRU" - WHERE it.entry IN (?a)', + WHERE it.entry IN %in', $moneyItems ); @@ -53,16 +53,16 @@ CLISetup::registerSetup("sql", new class extends SetupScript $strings = ['name_loc0' => 'Item #'.$itemId.' not in DB', 'iconId' => 0, 'cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3]; } - DB::Aowow()->query('UPDATE ?_currencies SET ?a WHERE itemId = ?d', $strings, $itemId); + DB::Aowow()->qry('UPDATE ::currencies SET %a WHERE itemId = %i', $strings, $itemId); } // apply icons - $displayIds = DB::World()->selectCol('SELECT `entry` AS ARRAY_KEY, `displayid` FROM item_template WHERE `entry` IN (?a)', $moneyItems); + $displayIds = DB::World()->selectCol('SELECT `entry` AS ARRAY_KEY, `displayid` FROM item_template WHERE `entry` IN %in', $moneyItems); foreach ($displayIds as $itemId => $iconId) - DB::Aowow()->query( - 'UPDATE ?_currencies c, ?_icons i, dbc_itemdisplayinfo idi + DB::Aowow()->qry( + 'UPDATE ::currencies c, ::icons i, dbc_itemdisplayinfo idi SET c.`iconId` = i.`id` - WHERE i.`name_source` = LOWER(idi.`inventoryIcon1`) AND idi.`id` = ?d AND c.`itemId` = ?d', + WHERE i.`name_source` = LOWER(idi.`inventoryIcon1`) AND idi.`id` = %i AND c.`itemId` = %i', $iconId, $itemId ); diff --git a/setup/tools/sqlgen/declinedword.ss.php b/setup/tools/sqlgen/declinedword.ss.php index e0837c70..2173f03a 100644 --- a/setup/tools/sqlgen/declinedword.ss.php +++ b/setup/tools/sqlgen/declinedword.ss.php @@ -17,15 +17,15 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['declinedword', 'declinedwordcases']; - public function generate(array $ids = []) : bool + public function generate() : bool { CLI::write('[declinedwords] - copying declinedword.dbc into aowow_declinedword'); - DB::Aowow()->query('TRUNCATE ?_declinedword'); - DB::Aowow()->query('INSERT INTO ?_declinedword SELECT * FROM dbc_declinedword'); + DB::Aowow()->qry('TRUNCATE ::declinedword'); + DB::Aowow()->qry('INSERT INTO ::declinedword SELECT * FROM dbc_declinedword'); CLI::write('[declinedwords] - copying declinedwordcases.dbc into aowow_declinedwordcases'); - DB::Aowow()->query('TRUNCATE ?_declinedwordcases'); - DB::Aowow()->query('INSERT INTO ?_declinedwordcases SELECT `wordId`, `caseIdx`, `word` FROM dbc_declinedwordcases'); + DB::Aowow()->qry('TRUNCATE ::declinedwordcases'); + DB::Aowow()->qry('INSERT INTO ::declinedwordcases SELECT `wordId`, `caseIdx`, `word` FROM dbc_declinedwordcases'); return true; } diff --git a/setup/tools/sqlgen/emotes.ss.php b/setup/tools/sqlgen/emotes.ss.php index 6a3258ca..0492acbf 100644 --- a/setup/tools/sqlgen/emotes.ss.php +++ b/setup/tools/sqlgen/emotes.ss.php @@ -20,7 +20,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript private $textData = []; - public function generate(array $ids = []) : bool + public function generate() : bool { $globStrPath = CLISetup::$srcDir.'%sInterface/FrameXML/GlobalStrings.lua'; $allOK = true; @@ -33,8 +33,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write(' Emote aliasses can not be generated for affected locales!', CLI::LOG_WARN); } - DB::Aowow()->query('TRUNCATE ?_emotes'); - DB::Aowow()->query('TRUNCATE ?_emotes_aliasses'); + DB::Aowow()->qry('TRUNCATE ::emotes'); + DB::Aowow()->qry('TRUNCATE ::emotes_aliasses'); /*********************/ @@ -53,13 +53,13 @@ CLISetup::registerSetup("sql", new class extends SetupScript 12 female others no ext -> none 4 - */ - $this->textData = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `text_loc0` AS "0", `text_loc2` AS "2", `text_loc3` AS "3", `text_loc4` AS "4", `text_loc6` AS "6", `text_loc8` AS "8" FROM dbc_emotestextdata'); + $this->textData = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `text_loc0` AS "0", `text_loc2` AS "2", `text_loc3` AS "3", `text_loc4` AS "4", `text_loc6` AS "6", `text_loc8` AS "8" FROM dbc_emotestextdata'); - $texts = DB::Aowow()->select('SELECT et.`id` AS ARRAY_KEY, LOWER(`command`) AS "cmd", IF(e.`animationId`, 1, 0) AS "anim", -`emoteId` AS "parent", e.`soundId`, `etd0`, `etd1`, `etd2`, `etd4`, `etd6`, `etd8`, `etd9`, `etd12` FROM dbc_emotestext et LEFT JOIN dbc_emotes e ON e.`id` = et.`emoteId`'); + $texts = DB::Aowow()->selectAssoc('SELECT et.`id` AS ARRAY_KEY, LOWER(`command`) AS "cmd", IF(e.`animationId`, 1, 0) AS "anim", -`emoteId` AS "parent", e.`soundId`, `etd0`, `etd1`, `etd2`, `etd4`, `etd6`, `etd8`, `etd9`, `etd12` FROM dbc_emotestext et LEFT JOIN dbc_emotes e ON e.`id` = et.`emoteId`'); foreach ($texts AS $id => $t) { - DB::Aowow()->query( - 'INSERT INTO ?_emotes ( + DB::Aowow()->qry( + 'INSERT INTO ::emotes ( `id`, `cmd`, `isAnimated`, `parentEmote`, `soundId`, `extToExt_loc0`, `extToMe_loc0`, `meToExt_loc0`, `extToNone_loc0`, `meToNone_loc0`, `extToExt_loc2`, `extToMe_loc2`, `meToExt_loc2`, `extToNone_loc2`, `meToNone_loc2`, @@ -68,7 +68,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript `extToExt_loc6`, `extToMe_loc6`, `meToExt_loc6`, `extToNone_loc6`, `meToNone_loc6`, `extToExt_loc8`, `extToMe_loc8`, `meToExt_loc8`, `extToNone_loc8`, `meToNone_loc8`) VALUES - (?d, ?, ?d, ?d, ?d, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + (%i, %s, %i, %i, %i, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)', $id, $t['cmd'], $t['anim'], $t['parent'], $t['soundId'], $this->mergeGenderedStrings($t['etd0'], $t['etd8'], Locale::EN), $this->mergeGenderedStrings($t['etd1'], $t['etd9'], Locale::EN), $this->textData[$t['etd2']][Locale::EN->value] ?? '', $this->mergeGenderedStrings($t['etd4'], $t['etd12'], Locale::EN), $this->textData[$t['etd6']][Locale::EN->value] ?? '', $this->mergeGenderedStrings($t['etd0'], $t['etd8'], Locale::FR), $this->mergeGenderedStrings($t['etd1'], $t['etd9'], Locale::FR), $this->textData[$t['etd2']][Locale::FR->value] ?? '', $this->mergeGenderedStrings($t['etd4'], $t['etd12'], Locale::FR), $this->textData[$t['etd6']][Locale::FR->value] ?? '', @@ -88,12 +88,12 @@ CLISetup::registerSetup("sql", new class extends SetupScript foreach (CLISetup::searchGlobalStrings('/^VOICEMACRO_LABEL_([A-Z]+)\d+ = \"([^"]+)\";$/') as $locId => [, $cmd, $alias]) $voiceAliases[$cmd][] = [$locId, $alias]; - $emotes = DB::Aowow()->selectCol('SELECT id AS ARRAY_KEY, cmd FROM ?_emotes'); + $emotes = DB::Aowow()->selectCol('SELECT id AS ARRAY_KEY, cmd FROM ::emotes'); foreach($emotes as $eId => $cmd) { foreach ($voiceAliases[strtoupper($cmd)] ?? [] as [$locId, $alias]) - DB::Aowow()->query('INSERT IGNORE INTO ?_emotes_aliasses VALUES (?d, ?d, ?) ON DUPLICATE KEY UPDATE `locales` = `locales` | ?d', $eId, (1 << $locId), mb_strtolower($alias), (1 << $locId)); + DB::Aowow()->qry('INSERT IGNORE INTO ::emotes_aliasses VALUES (%i, %i, %s) ON DUPLICATE KEY UPDATE `locales` = `locales` | %i', $eId, (1 << $locId), mb_strtolower($alias), (1 << $locId)); foreach ($aliasses as $data) { @@ -101,20 +101,20 @@ CLISetup::registerSetup("sql", new class extends SetupScript continue; foreach ($data as [$locId, $alias]) - DB::Aowow()->query('INSERT IGNORE INTO ?_emotes_aliasses VALUES (?d, ?d, ?) ON DUPLICATE KEY UPDATE `locales` = `locales` | ?d', $eId, (1 << $locId), mb_strtolower($alias), (1 << $locId)); + DB::Aowow()->qry('INSERT IGNORE INTO ::emotes_aliasses VALUES (%i, %i, %s) ON DUPLICATE KEY UPDATE `locales` = `locales` | %i', $eId, (1 << $locId), mb_strtolower($alias), (1 << $locId)); break; } } - DB::Aowow()->query('UPDATE ?_emotes e LEFT JOIN ?_emotes_aliasses ea ON ea.`id` = e.`id` SET e.`cuFlags` = e.`cuFlags` | ?d WHERE ea.`id` IS NULL', CUSTOM_EXCLUDE_FOR_LISTVIEW | EMOTE_CU_MISSING_CMD); + DB::Aowow()->qry('UPDATE ::emotes e LEFT JOIN ::emotes_aliasses ea ON ea.`id` = e.`id` SET e.`cuFlags` = e.`cuFlags` | %i WHERE ea.`id` IS NULL', CUSTOM_EXCLUDE_FOR_LISTVIEW | EMOTE_CU_MISSING_CMD); /*********************/ /* Server controlled */ /*********************/ - DB::Aowow()->query('INSERT INTO ?_emotes (`id`, `cmd`, `flags`, `isAnimated`, `parentEmote`, `soundId`, `state`, `stateParam`, `cuFlags`) SELECT -`id`, `name`, `flags`, IF(`animationId`, 1, 0), 0, `soundId`, `state`, `stateParam`, ?d FROM dbc_emotes WHERE 1', CUSTOM_EXCLUDE_FOR_LISTVIEW); + DB::Aowow()->qry('INSERT INTO ::emotes (`id`, `cmd`, `flags`, `isAnimated`, `parentEmote`, `soundId`, `state`, `stateParam`, `cuFlags`) SELECT -`id`, `name`, `flags`, IF(`animationId`, 1, 0), 0, `soundId`, `state`, `stateParam`, %i FROM dbc_emotes WHERE 1', CUSTOM_EXCLUDE_FOR_LISTVIEW); $this->reapplyCCFlags('emotes', Type::EMOTE); diff --git a/setup/tools/sqlgen/events.ss.php b/setup/tools/sqlgen/events.ss.php index d1860b92..1cfdda26 100644 --- a/setup/tools/sqlgen/events.ss.php +++ b/setup/tools/sqlgen/events.ss.php @@ -17,11 +17,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $worldDependency = ['game_event', 'game_event_prerequisite']; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_events'); + DB::Aowow()->qry('TRUNCATE ::events'); - $events = DB::World()->select( + $events = DB::World()->selectAssoc( 'SELECT ge.eventEntry, holiday, 0, -- cuFlags @@ -33,13 +33,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript description FROM game_event ge LEFT JOIN game_event_prerequisite gep ON gep.eventEntry = ge.eventEntry - { WHERE ge.eventEntry IN (?a) } GROUP BY ge.eventEntry', - $ids ?: DBSIMPLE_SKIP ); foreach ($events as $e) - DB::Aowow()->query('INSERT INTO ?_events VALUES (?a)', array_values($e)); + DB::Aowow()->qry('INSERT INTO ::events VALUES %l', $e); $this->reapplyCCFlags('events', Type::WORLDEVENT); diff --git a/setup/tools/sqlgen/factions.ss.php b/setup/tools/sqlgen/factions.ss.php index fda498d8..d62eba8f 100644 --- a/setup/tools/sqlgen/factions.ss.php +++ b/setup/tools/sqlgen/factions.ss.php @@ -19,13 +19,13 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['faction', 'factiontemplate']; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_factions'); - DB::Aowow()->query('TRUNCATE ?_factiontemplate'); + DB::Aowow()->qry('TRUNCATE ::factions'); + DB::Aowow()->qry('TRUNCATE ::factiontemplate'); - DB::Aowow()->query( - 'INSERT INTO ?_factions + DB::Aowow()->qry( + 'INSERT INTO ::factions SELECT f.`id`, f.`repIdx`, `baseRepRaceMask1`, `baseRepRaceMask2`, `baseRepRaceMask3`, `baseRepRaceMask4`, @@ -44,8 +44,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript GROUP BY f.`id`' ); - DB::Aowow()->query( - 'INSERT INTO ?_factiontemplate + DB::Aowow()->qry( + 'INSERT INTO ::factiontemplate SELECT `id`, `factionId`, IF(`friendFactionId1` = 1 OR `friendFactionId2` = 1 OR `friendFactionId3` = 1 OR `friendFactionId4` = 1 OR `friendlyMask` & 0x3, 1, @@ -55,36 +55,36 @@ CLISetup::registerSetup("sql", new class extends SetupScript FROM dbc_factiontemplate' ); - DB::Aowow()->query( - 'UPDATE ?_factions f + DB::Aowow()->qry( + 'UPDATE ::factions f JOIN (SELECT ft.`factionId`, GROUP_CONCAT(ft.`id` SEPARATOR " ") AS "tplIds" FROM dbc_factiontemplate ft GROUP BY ft.`factionId`) temp ON f.`id` = temp.`factionId` SET f.`templateIds` = temp.`tplIds`' ); - DB::Aowow()->query( - 'UPDATE ?_factions x + DB::Aowow()->qry( + 'UPDATE ::factions x JOIN dbc_faction f ON f.`id` = x.`id` - SET `cuFlags` = `cuFlags` | ?d - WHERE f.`repIdx` < 0 OR f.`id` = 952 OR ( (f.`repFlags1` & ?d) > 0 AND f.`id` NOT IN (67, 169, 469, 589, 1085) AND (f.`repFLags1` & ?d) = 0 )', + SET `cuFlags` = `cuFlags` | %i + WHERE f.`repIdx` < 0 OR f.`id` = 952 OR ( (f.`repFlags1` & %i) > 0 AND f.`id` NOT IN (67, 169, 469, 589, 1085) AND (f.`repFLags1` & %i) = 0 )', CUSTOM_EXCLUDE_FOR_LISTVIEW, FACTION_FLAG_HIDDEN | FACTION_FLAG_INVISIBLE_FORCED, FACTION_FLAG_SPECIAL ); $pairs = array( - [[980], ['expansion' => 1]], - [[1097], ['expansion' => 2]], - [[469, 891, 1037], ['side' => 1]], - [[ 67, 892, 1052], ['side' => 2]], + [[980], ['expansion' => EXP_BC]], + [[1097], ['expansion' => EXP_WOTLK]], + [[469, 891, 1037], ['side' => SIDE_ALLIANCE]], + [[ 67, 892, 1052], ['side' => SIDE_HORDE]], ); - foreach ($pairs as $p) - DB::Aowow()->query( - 'UPDATE ?_factions top - JOIN (SELECT `id`, `parentFactionId` FROM ?_factions) mid ON mid.`parentFactionId` IN (?a) - LEFT JOIN (SELECT `id`, `parentFactionId` FROM ?_factions) low ON low.`parentFactionId` = mid.`id` - SET ?a - WHERE `repIdx` > 0 AND (top.`id` IN (?a) OR top.`id` = mid.`id` OR top.`id` = low.`id`)', - $p[0], $p[1], $p[0] + foreach ($pairs as [$factions, $update]) + DB::Aowow()->qry( + 'UPDATE ::factions top + JOIN (SELECT `id`, `parentFactionId` FROM ::factions) mid ON mid.`parentFactionId` IN %in + LEFT JOIN (SELECT `id`, `parentFactionId` FROM ::factions) low ON low.`parentFactionId` = mid.`id` + SET %a + WHERE `repIdx` > 0 AND (top.`id` IN %in OR top.`id` = mid.`id` OR top.`id` = low.`id`)', + $factions, $update, $factions ); $this->reapplyCCFlags('factions', Type::FACTION); diff --git a/setup/tools/sqlgen/glyphproperties.ss.php b/setup/tools/sqlgen/glyphproperties.ss.php index 51fdf7c1..53736593 100644 --- a/setup/tools/sqlgen/glyphproperties.ss.php +++ b/setup/tools/sqlgen/glyphproperties.ss.php @@ -18,12 +18,12 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['glyphproperties', 'spellicon']; protected $setupAfter = [['icons'], []]; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_glyphproperties'); - DB::Aowow()->query('INSERT INTO ?_glyphproperties SELECT id, spellId, typeFlags, 0, iconId FROM dbc_glyphproperties'); + DB::Aowow()->qry('TRUNCATE ::glyphproperties'); + DB::Aowow()->qry('INSERT INTO ::glyphproperties SELECT `id`, `spellId`, `typeFlags`, 0, `iconId` FROM dbc_glyphproperties'); - DB::Aowow()->query('UPDATE ?_glyphproperties gp, ?_icons ic, dbc_spellicon si SET gp.iconId = ic.id WHERE gp.iconIdBak = si.id AND ic.name_source = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1))'); + DB::Aowow()->qry('UPDATE ::glyphproperties gp, ::icons ic, dbc_spellicon si SET gp.`iconId` = ic.`id` WHERE gp.`iconIdBak` = si.`id` AND ic.`name_source` = LOWER(SUBSTRING_INDEX(si.`iconPath`, "\\", -1))'); return true; } diff --git a/setup/tools/sqlgen/holidays.ss.php b/setup/tools/sqlgen/holidays.ss.php index a9ebbe67..2f79c122 100644 --- a/setup/tools/sqlgen/holidays.ss.php +++ b/setup/tools/sqlgen/holidays.ss.php @@ -31,11 +31,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $setupAfter = [['icons'], []]; protected $dbcSourceFiles = ['holidays', 'holidaydescriptions', 'holidaynames']; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_holidays'); - DB::Aowow()->query( - 'INSERT INTO ?_holidays (`id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `description_loc0`, `description_loc2`, `description_loc3`, `description_loc4`, `description_loc6`, `description_loc8`, `looping`, `scheduleType`, `textureString`) + DB::Aowow()->qry('TRUNCATE ::holidays'); + DB::Aowow()->qry( + 'INSERT INTO ::holidays (`id`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `description_loc0`, `description_loc2`, `description_loc3`, `description_loc4`, `description_loc6`, `description_loc8`, `looping`, `scheduleType`, `textureString`) SELECT h.`id`, n.`name_loc0`, n.`name_loc2`, n.`name_loc3`, n.`name_loc4`, n.`name_loc6`, n.`name_loc8`, d.`description_loc0`, d.`description_loc2`, d.`description_loc3`, d.`description_loc4`, d.`description_loc6`, d.`description_loc8`, h.`looping`, h.`scheduleType`, h.`textureString` FROM dbc_holidays h LEFT JOIN dbc_holidaynames n ON n.`id` = h.`nameId` @@ -43,11 +43,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript ); // set derived icons - DB::Aowow()->query('UPDATE ?_holidays h, ?_icons i SET h.`iconId` = i.`id` WHERE i.`name_source` LIKE CONCAT(LOWER(h.`textureString`), "%") AND h.`textureString` <> ""'); + DB::Aowow()->qry('UPDATE ::holidays h, ::icons i SET h.`iconId` = i.`id` WHERE i.`name_source` LIKE CONCAT(LOWER(h.`textureString`), "%") AND h.`textureString` <> ""'); // set custom icons foreach (self::CUSTOM_ICONS as $hId => $iconString) - DB::Aowow()->query('UPDATE ?_holidays h SET h.`iconId` = (SELECT i.`id` FROM ?_icons i WHERE `name_source` = ?) WHERE `id` = ?d', $iconString, $hId); + DB::Aowow()->qry('UPDATE ::holidays h SET h.`iconId` = (SELECT i.`id` FROM ::icons i WHERE `name_source` = ?) WHERE `id` = %i', $iconString, $hId); return true; } diff --git a/setup/tools/sqlgen/icons.ss.php b/setup/tools/sqlgen/icons.ss.php index 87269d88..d41fac0f 100644 --- a/setup/tools/sqlgen/icons.ss.php +++ b/setup/tools/sqlgen/icons.ss.php @@ -37,36 +37,36 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['spellicon', 'itemdisplayinfo', 'creaturefamily']; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_icons'); - DB::Aowow()->query('ALTER TABLE ?_icons AUTO_INCREMENT = 1'); - DB::Aowow()->query( - 'INSERT INTO ?_icons (`name`, `name_source`) SELECT REGEXP_REPLACE(x, "\\\\W", "-"), x FROM + DB::Aowow()->qry('TRUNCATE ::icons'); + DB::Aowow()->qry('ALTER TABLE ::icons AUTO_INCREMENT = 1'); + DB::Aowow()->qry( + 'INSERT INTO ::icons (`name`, `name_source`) SELECT REGEXP_REPLACE(x, "\\W", "-"), x FROM ( - (SELECT LOWER(SUBSTRING_INDEX(`iconPath`, "\\\\", -1)) AS x FROM dbc_spellicon WHERE `iconPath` LIKE "%icons%") UNION - (SELECT LOWER(`inventoryIcon1`) AS x FROM dbc_itemdisplayinfo WHERE `inventoryIcon1` <> "") UNION - (SELECT LOWER(SUBSTRING_INDEX(`iconString`, "\\\\", -1)) AS x FROM dbc_creaturefamily WHERE `iconString` LIKE "%icons%") + (SELECT LOWER(SUBSTRING_INDEX(`iconPath`, "\\", -1)) AS x FROM dbc_spellicon WHERE `iconPath` LIKE "%icons%") UNION + (SELECT LOWER(`inventoryIcon1`) AS x FROM dbc_itemdisplayinfo WHERE `inventoryIcon1` <> "") UNION + (SELECT LOWER(SUBSTRING_INDEX(`iconString`, "\\", -1)) AS x FROM dbc_creaturefamily WHERE `iconString` LIKE "%icons%") ) y GROUP BY x' ); // invent class icons foreach (ChrClass::cases() as $cl) - DB::Aowow()->query('INSERT INTO ?_icons (`name`, `name_source`) VALUES (?, ?)', 'class_'.$cl->json(), 'class_'.$cl->json()); + DB::Aowow()->qry('INSERT INTO ::icons (`name`, `name_source`) VALUES (%s, %s)', 'class_'.$cl->json(), 'class_'.$cl->json()); // invent race icons foreach (ChrRace::cases() as $ra) { if ($na = $ra->json()) // unused races have no json { - DB::Aowow()->query('INSERT INTO ?_icons (`name`, `name_source`) VALUES (?, ?)', 'race_'.$na.'_male', 'race_'.$na.'_male'); - DB::Aowow()->query('INSERT INTO ?_icons (`name`, `name_source`) VALUES (?, ?)', 'race_'.$na.'_female', 'race_'.$na.'_female'); + DB::Aowow()->qry('INSERT INTO ::icons (`name`, `name_source`) VALUES (%s, %s)', 'race_'.$na.'_male', 'race_'.$na.'_male'); + DB::Aowow()->qry('INSERT INTO ::icons (`name`, `name_source`) VALUES (%s, %s)', 'race_'.$na.'_female', 'race_'.$na.'_female'); } } // halucinate holidays foreach (self::HOLIDAY_ICONS as $h) - DB::Aowow()->query('INSERT INTO ?_icons (`name`, `name_source`) VALUES (?, ?)', $h, $h); + DB::Aowow()->qry('INSERT INTO ::icons (`name`, `name_source`) VALUES (%s, %s)', $h, $h); $this->reapplyCCFlags('icons', Type::ICON); diff --git a/setup/tools/sqlgen/itemenchantment.ss.php b/setup/tools/sqlgen/itemenchantment.ss.php index 6dfa1505..ac118862 100644 --- a/setup/tools/sqlgen/itemenchantment.ss.php +++ b/setup/tools/sqlgen/itemenchantment.ss.php @@ -18,22 +18,22 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['spellitemenchantment']; protected $worldDependency = ['spell_enchant_proc_data']; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_itemenchantment'); - DB::Aowow()->query( - 'INSERT INTO ?_itemenchantment + DB::Aowow()->qry('TRUNCATE ::itemenchantment'); + DB::Aowow()->qry( + 'INSERT INTO ::itemenchantment SELECT `Id`, `charges`, 0, 0, 0, `type1`, `type2`, `type3`, `amount1`, `amount2`, `amount3`, `object1`, `object2`, `object3`, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `conditionId`, `skillLine`, `skillLevel`, `requiredLevel` FROM dbc_spellitemenchantment' ); - $cuProcs = DB::World()->select('SELECT `EnchantID` AS ARRAY_KEY, `Chance` AS `procChance`, `ProcsPerMinute` AS `ppmRate` FROM spell_enchant_proc_data'); + $cuProcs = DB::World()->selectAssoc('SELECT `EnchantID` AS ARRAY_KEY, `Chance` AS `procChance`, `ProcsPerMinute` AS `ppmRate` FROM spell_enchant_proc_data'); foreach ($cuProcs as $id => $vals) - DB::Aowow()->query('UPDATE ?_itemenchantment SET ?a WHERE `id` = ?d', $vals, $id); + DB::Aowow()->qry('UPDATE ::itemenchantment SET %a WHERE `id` = %i', $vals, $id); // hide strange stuff - DB::Aowow()->query('UPDATE ?_itemenchantment SET `cuFlags` = ?d WHERE `type1` = 0 AND `type2` = 0 AND `type3` = 0', CUSTOM_EXCLUDE_FOR_LISTVIEW); - DB::Aowow()->query('UPDATE ?_itemenchantment SET `cuFlags` = ?d WHERE `name_loc0` LIKE "%test%"', CUSTOM_EXCLUDE_FOR_LISTVIEW); + DB::Aowow()->qry('UPDATE ::itemenchantment SET `cuFlags` = %i WHERE `type1` = 0 AND `type2` = 0 AND `type3` = 0', CUSTOM_EXCLUDE_FOR_LISTVIEW); + DB::Aowow()->qry('UPDATE ::itemenchantment SET `cuFlags` = %i WHERE `name_loc0` LIKE "%test%"', CUSTOM_EXCLUDE_FOR_LISTVIEW); $this->reapplyCCFlags('itemenchantment', Type::ENCHANTMENT); diff --git a/setup/tools/sqlgen/itemrandomenchant.ss.php b/setup/tools/sqlgen/itemrandomenchant.ss.php index 2f72ba67..a6c7cde3 100644 --- a/setup/tools/sqlgen/itemrandomenchant.ss.php +++ b/setup/tools/sqlgen/itemrandomenchant.ss.php @@ -17,11 +17,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['itemrandomsuffix', 'itemrandomproperties']; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_itemrandomenchant'); - DB::Aowow()->query( - 'INSERT INTO ?_itemrandomenchant + DB::Aowow()->qry('TRUNCATE ::itemrandomenchant'); + DB::Aowow()->qry( + 'INSERT INTO ::itemrandomenchant SELECT -id, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, nameINT, enchantId1, enchantId2, enchantId3, enchantId4, enchantId5, allocationPct1, allocationPct2, allocationPct3, allocationPct4, allocationPct5 FROM dbc_itemrandomsuffix UNION SELECT id, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, nameINT, enchantId1, enchantId2, enchantId3, enchantId4, enchantId5, 0, 0, 0, 0, 0 FROM dbc_itemrandomproperties' ); diff --git a/setup/tools/sqlgen/items.ss.php b/setup/tools/sqlgen/items.ss.php index ae1e2451..4a1de925 100644 --- a/setup/tools/sqlgen/items.ss.php +++ b/setup/tools/sqlgen/items.ss.php @@ -29,7 +29,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript SKILL_ALCHEMY => 6 ); - public function generate(array $ids = []) : bool + public function generate() : bool { $baseQuery = 'SELECT it.entry, @@ -128,39 +128,38 @@ CLISetup::registerSetup("sql", new class extends SetupScript LEFT JOIN item_template_locale itl8 ON it.entry = itl8.ID AND itl8.locale = "ruRU" LEFT JOIN spell_group sg ON sg.spell_id = it.spellid_1 AND it.class = 0 AND it.subclass = 2 AND sg.id IN (1, 2) LEFT JOIN game_event ge ON ge.holiday = it.HolidayId AND it.HolidayId > 0 - { WHERE it.entry IN (?a) } - LIMIT ?d, ?d'; + LIMIT %i, %i'; - DB::Aowow()->query('TRUNCATE ?_items'); - DB::Aowow()->query('SET SESSION innodb_ft_enable_stopword = OFF'); + DB::Aowow()->qry('TRUNCATE ::items'); + DB::Aowow()->qry('SET SESSION innodb_ft_enable_stopword = OFF'); $i = 0; - while ($items = DB::World()->select($baseQuery, $ids ?: DBSIMPLE_SKIP, CLISetup::SQL_BATCH * $i, CLISetup::SQL_BATCH)) + while ($items = DB::World()->selectAssoc($baseQuery, CLISetup::SQL_BATCH * $i, CLISetup::SQL_BATCH)) { CLI::write(' * batch #' . ++$i . ' (' . count($items) . ')', tmpRow: true); foreach ($items as $item) - DB::Aowow()->query('INSERT INTO ?_items VALUES (?a)', array_values($item)); + DB::Aowow()->qry('INSERT INTO ::items VALUES %l', $item); } CLI::write('[items] - applying misc data & fixes'); // merge with gemProperties - DB::Aowow()->query('UPDATE ?_items i, dbc_gemproperties gp SET i.gemEnchantmentId = gp.enchantmentId, i.gemColorMask = gp.colorMask WHERE i.gemColorMask = gp.id'); + DB::Aowow()->qry('UPDATE ::items i, dbc_gemproperties gp SET i.gemEnchantmentId = gp.enchantmentId, i.gemColorMask = gp.colorMask WHERE i.gemColorMask = gp.id'); // get modelString - DB::Aowow()->query('UPDATE ?_items i, dbc_itemdisplayinfo idi SET i.model = IF(idi.leftModelName = "", idi.rightModelName, idi.leftModelName) WHERE i.displayId = idi.id'); + DB::Aowow()->qry('UPDATE ::items i, dbc_itemdisplayinfo idi SET i.model = IF(idi.leftModelName = "", idi.rightModelName, idi.leftModelName) WHERE i.displayId = idi.id'); // get iconId - DB::Aowow()->query('UPDATE ?_items i, dbc_itemdisplayinfo idi, ?_icons ic SET i.iconId = ic.id WHERE i.displayId = idi.id AND LOWER(idi.inventoryIcon1) = ic.name_source'); + DB::Aowow()->qry('UPDATE ::items i, dbc_itemdisplayinfo idi, ::icons ic SET i.iconId = ic.id WHERE i.displayId = idi.id AND LOWER(idi.inventoryIcon1) = ic.name_source'); // unify slots: Robes => Chest; Ranged (right) => Ranged - DB::Aowow()->query('UPDATE ?_items SET slot = ?d WHERE slotbak = ?d', INVTYPE_RANGED, INVTYPE_RANGEDRIGHT); - DB::Aowow()->query('UPDATE ?_items SET slot = ?d WHERE slotbak = ?d', INVTYPE_CHEST, INVTYPE_ROBE); + DB::Aowow()->qry('UPDATE ::items SET slot = %i WHERE slotbak = %i', INVTYPE_RANGED, INVTYPE_RANGEDRIGHT); + DB::Aowow()->qry('UPDATE ::items SET slot = %i WHERE slotbak = %i', INVTYPE_CHEST, INVTYPE_ROBE); // custom sub-classes - DB::Aowow()->query( - 'UPDATE ?_items SET subclass = IF( + DB::Aowow()->qry( + 'UPDATE ::items SET subclass = IF( slotbak = 4, -8, IF( -- shirt slotbak = 19, -7, IF( -- tabard slotbak = 16, -6, IF( -- cloak @@ -172,49 +171,49 @@ CLISetup::registerSetup("sql", new class extends SetupScript ); // move alchemist stones to trinkets (Armor) - DB::Aowow()->query('UPDATE ?_items SET class = 4, subClass = -4 WHERE classBak = 7 AND subClassBak = 11 AND slotBak = ?d', INVTYPE_TRINKET); + DB::Aowow()->qry('UPDATE ::items SET class = 4, subClass = -4 WHERE classBak = 7 AND subClassBak = 11 AND slotBak = %i', INVTYPE_TRINKET); // mark keys as key (if not quest items) - DB::Aowow()->query('UPDATE ?_items SET class = 13, subClass = 0 WHERE classBak IN (0, 15) AND bagFamily & 0x100'); + DB::Aowow()->qry('UPDATE ::items SET class = 13, subClass = 0 WHERE classBak IN (0, 15) AND bagFamily & 0x100'); // set subSubClass for Glyphs (major/minor) - DB::Aowow()->query('UPDATE ?_items i, dbc_spell s, dbc_glyphproperties gp SET i.subSubClass = IF(gp.typeFlags & 0x1, 2, 1) WHERE i.spellId1 = s.id AND s.effect1MiscValue = gp.id AND i.classBak = 16'); + DB::Aowow()->qry('UPDATE ::items i, dbc_spell s, dbc_glyphproperties gp SET i.subSubClass = IF(gp.typeFlags & 0x1, 2, 1) WHERE i.spellId1 = s.id AND s.effect1MiscValue = gp.id AND i.classBak = 16'); // filter misc(class:15) junk(subclass:0) to appropriate categories // assign pets and mounts to category - DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET subClass = IF(effect1AuraId <> 78, 2, IF(effect2AuraId = 207 OR effect3AuraId = 207 OR (s.id <> 65917 AND effect2AuraId = 4 AND effect3Id = 77), -7, 5)) WHERE s.id = spellId2 AND class = 15 AND spellId1 IN (?a)', LEARN_SPELLS); + DB::Aowow()->qry('UPDATE ::items i, dbc_spell s SET subClass = IF(effect1AuraId <> 78, 2, IF(effect2AuraId = 207 OR effect3AuraId = 207 OR (s.id <> 65917 AND effect2AuraId = 4 AND effect3Id = 77), -7, 5)) WHERE s.id = spellId2 AND class = 15 AND spellId1 IN %in', LEARN_SPELLS); // more corner cases (mounts that are not actualy learned) - DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.subClass = -7 WHERE (effect1Id = 64 OR (effect1AuraId = 78 AND effect2AuraId = 4 AND effect3Id = 77) OR effect1AuraId = 207 OR effect2AuraId = 207 OR effect3AuraId = 207) AND s.id = i.spellId1 AND i.class = 15 AND i.subClass = 5'); - DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.subClass = 5 WHERE s.effect1AuraId = 78 AND s.id = i.spellId1 AND i.class = 15 AND i.subClass = 0'); + DB::Aowow()->qry('UPDATE ::items i, dbc_spell s SET i.subClass = -7 WHERE (effect1Id = 64 OR (effect1AuraId = 78 AND effect2AuraId = 4 AND effect3Id = 77) OR effect1AuraId = 207 OR effect2AuraId = 207 OR effect3AuraId = 207) AND s.id = i.spellId1 AND i.class = 15 AND i.subClass = 5'); + DB::Aowow()->qry('UPDATE ::items i, dbc_spell s SET i.subClass = 5 WHERE s.effect1AuraId = 78 AND s.id = i.spellId1 AND i.class = 15 AND i.subClass = 0'); // move some permanent enchantments to own category - DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.class = 0, i.subClass = 6 WHERE s.effect1Id = 53 AND s.id = i.spellId1 AND i.class = 15'); + DB::Aowow()->qry('UPDATE ::items i, dbc_spell s SET i.class = 0, i.subClass = 6 WHERE s.effect1Id = 53 AND s.id = i.spellId1 AND i.class = 15'); // move temporary enchantments to own category - DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.subClass = -3 WHERE s.effect1Id = 54 AND s.id = i.spellId1 AND i.class = 0 AND i.subClassBak = 8'); + DB::Aowow()->qry('UPDATE ::items i, dbc_spell s SET i.subClass = -3 WHERE s.effect1Id = 54 AND s.id = i.spellId1 AND i.class = 0 AND i.subClassBak = 8'); // move armor tokens to own category - DB::Aowow()->query('UPDATE ?_items SET subClass = -2 WHERE quality = 4 AND class = 15 AND subClassBak = 0 AND requiredClass > 0'); + DB::Aowow()->qry('UPDATE ::items SET subClass = -2 WHERE quality = 4 AND class = 15 AND subClassBak = 0 AND requiredClass > 0'); // move some junk to holiday if it requires one - DB::Aowow()->query('UPDATE ?_items SET subClass = 3 WHERE classBak = 15 AND subClassBak = 0 AND eventId <> 0'); + DB::Aowow()->qry('UPDATE ::items SET subClass = 3 WHERE classBak = 15 AND subClassBak = 0 AND eventId <> 0'); // move misc items that start quests to class: quest (except Sayges scrolls for consistency) - DB::Aowow()->query('UPDATE ?_items SET class = 12 WHERE classBak = 15 AND startQuest <> 0 AND name_loc0 NOT LIKE "sayge\'s fortune%"'); + DB::Aowow()->qry('UPDATE ::items SET class = 12 WHERE classBak = 15 AND startQuest <> 0 AND name_loc0 NOT LIKE "sayge\'s fortune%"'); // move perm. enchantments into appropriate cat/subcat - DB::Aowow()->query('UPDATE ?_items i, dbc_spell s SET i.class = 0, i.subClass = 6 WHERE s.id = i.spellId1 AND s.effect1Id = 53 AND i.classBak = 12'); + DB::Aowow()->qry('UPDATE ::items i, dbc_spell s SET i.class = 0, i.subClass = 6 WHERE s.id = i.spellId1 AND s.effect1Id = 53 AND i.classBak = 12'); // move some generic recipes into appropriate sub-categories foreach (self::SKILL_CATG as $skill => $cat) - DB::Aowow()->query('UPDATE ?_items SET subClass = ?d WHERE classBak = 9 AND subClassBak = 0 AND requiredSkill = ?d', $cat, $skill); + DB::Aowow()->qry('UPDATE ::items SET subClass = %i WHERE classBak = 9 AND subClassBak = 0 AND requiredSkill = %i', $cat, $skill); // assign slot from onUse spell to item (todo (med): handle multi slot enchantments (like armor kits)) - DB::Aowow()->query( - 'UPDATE ?_items i - JOIN (SELECT `id`, LOG(2, `equippedItemInventoryTypeMask` & ~?d) AS `mask` + DB::Aowow()->qry( + 'UPDATE ::items i + JOIN (SELECT `id`, LOG(2, `equippedItemInventoryTypeMask` & ~%i) AS `mask` FROM dbc_spell WHERE `equippedItemInventoryTypeMask` > 0 HAVING CAST(`mask` AS UNSIGNED) = CAST(`mask` AS FLOAT)) s @@ -225,8 +224,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript ); // calculate durabilityCosts - DB::Aowow()->query( - 'UPDATE ?_items i + DB::Aowow()->qry( + 'UPDATE ::items i JOIN dbc_durabilityquality dq ON dq.id = ((i.quality + 1) * 2) JOIN dbc_durabilitycosts dc ON dc.id = i.itemLevel SET i.repairPrice = (durability * dq.mod * IF(i.classBak = 2, @@ -244,9 +243,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript ); // hide some nonsense - DB::Aowow()->query( - 'UPDATE ?_items - SET `cuFlags` = `cuFlags` | ?d + DB::Aowow()->qry( + 'UPDATE ::items + SET `cuFlags` = `cuFlags` | %i WHERE `name_loc0` LIKE "Monster - %" OR `name_loc0` LIKE "Creature - %" OR `name_loc0` LIKE "%[PH]%" OR `name_loc0` LIKE "% PH %" OR `name_loc0` LIKE "%(new)%" OR `name_loc0` LIKE "%(old)%" OR @@ -263,22 +262,22 @@ CLISetup::registerSetup("sql", new class extends SetupScript [[INVTYPE_RANGED, INVTYPE_RANGEDRIGHT], [2, 3, 16, 18, 14, 19]] ); foreach ($checks as [$slots, $subclasses]) - DB::Aowow()->query('UPDATE ?_items SET `cuFlags` = `cuFlags` | ?d WHERE `class`= ?d AND `slotBak` IN (?a) AND `subClass` NOT IN (?a)', CUSTOM_EXCLUDE_FOR_LISTVIEW, ITEM_CLASS_WEAPON, $slots, $subclasses); + DB::Aowow()->qry('UPDATE ::items SET `cuFlags` = `cuFlags` | %i WHERE `class`= %i AND `slotBak` IN %in AND `subClass` NOT IN %in', CUSTOM_EXCLUDE_FOR_LISTVIEW, ITEM_CLASS_WEAPON, $slots, $subclasses); CLI::write('[items] - collecting spell descriptions'); CLI::write(' * fetching', tmpRow: true); - $itemSpellData = DB::Aowow()->select( - 'SELECT `id` AS "0", `spellId1` AS "1" FROM ?_items WHERE `spellId1` > 0 UNION - SELECT `id` AS "0", `spellId2` AS "1" FROM ?_items WHERE `spellId2` > 0 UNION - SELECT `id` AS "0", `spellId3` AS "1" FROM ?_items WHERE `spellId3` > 0 UNION - SELECT `id` AS "0", `spellId4` AS "1" FROM ?_items WHERE `spellId4` > 0 UNION - SELECT `id` AS "0", `spellId5` AS "1" FROM ?_items WHERE `spellId5` > 0' + $itemSpellData = DB::Aowow()->selectAssoc( + 'SELECT `id` AS "0", `spellId1` AS "1" FROM ::items WHERE `spellId1` > 0 UNION + SELECT `id` AS "0", `spellId2` AS "1" FROM ::items WHERE `spellId2` > 0 UNION + SELECT `id` AS "0", `spellId3` AS "1" FROM ::items WHERE `spellId3` > 0 UNION + SELECT `id` AS "0", `spellId4` AS "1" FROM ::items WHERE `spellId4` > 0 UNION + SELECT `id` AS "0", `spellId5` AS "1" FROM ::items WHERE `spellId5` > 0' ); $itemSpells = new SpellList(array(['id', array_column($itemSpellData, 1)]), ['interactive' => SpellList::INTERACTIVE_NONE]); - $items = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `spellId1`, `spellId2`, `spellId3`, `spellId4`, `spellId5` FROM ?_items WHERE `id` IN (?a)', array_column($itemSpellData, 0)); + $items = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `spellId1`, `spellId2`, `spellId3`, `spellId4`, `spellId5` FROM ::items WHERE `id` IN %in', array_column($itemSpellData, 0)); if (!$itemSpells->error) { $i = 0; @@ -313,7 +312,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript foreach ($update as $itemId => $upd) { CLI::write(' * writing ' . str_pad(++$i, strlen($total), pad_type: STR_PAD_LEFT) . ' / ' . $total . str_pad('('.number_format(100 * $i / $total, 1).'%)', 8, pad_type: STR_PAD_LEFT), tmpRow: true); - DB::Aowow()->query('UPDATE ?_items SET ?a WHERE `id` = ?d', $upd, $itemId); + DB::Aowow()->qry('UPDATE ::items SET %a WHERE `id` = %i', $upd, $itemId); } } diff --git a/setup/tools/sqlgen/itemset.ss.php b/setup/tools/sqlgen/itemset.ss.php index 090db02e..eed06406 100644 --- a/setup/tools/sqlgen/itemset.ss.php +++ b/setup/tools/sqlgen/itemset.ss.php @@ -185,17 +185,17 @@ CLISetup::registerSetup("sql", new class extends SetupScript $data['contentGroup'] = reset($items)['note']; } - public function generate(array $ids = []) : bool + public function generate() : bool { // find events associated with holidayIds - if ($pairs = DB::World()->selectCol('SELECT `holiday` AS ARRAY_KEY, `eventEntry` FROM game_event WHERE `holiday` IN (?a)', array_values($this->setToHoliday))) + if ($pairs = DB::World()->selectCol('SELECT `holiday` AS ARRAY_KEY, `eventEntry` FROM game_event WHERE `holiday` IN %in', array_values($this->setToHoliday))) foreach ($this->setToHoliday as &$hId) $hId = !empty($pairs[$hId]) ? $pairs[$hId] : 0; - DB::Aowow()->query('TRUNCATE TABLE ?_itemset'); + DB::Aowow()->qry('TRUNCATE TABLE ::itemset'); $virtualId = 0; - $sets = DB::Aowow()->select('SELECT *, `id` AS ARRAY_KEY FROM dbc_itemset'); + $sets = DB::Aowow()->selectAssoc('SELECT *, `id` AS ARRAY_KEY FROM dbc_itemset'); $spells = array_merge( array_column($sets, 'spellId1'), array_column($sets, 'spellId2'), array_column($sets, 'spellId3'), array_column($sets, 'spellId4'), array_column($sets, 'spellId5'), array_column($sets, 'spellId6'), @@ -204,7 +204,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript $bonusSpells = new SpellList(array(['s.id', array_unique($spells)]), ['interactive' => SpellList::INTERACTIVE_NONE]); - $pieces = DB::World()->select('SELECT `itemset` AS ARRAY_KEY, `entry` AS ARRAY_KEY2, `entry`, `name`, `class`, `subclass`, `Quality`, `AllowableClass`, `ItemLevel`, `RequiredLevel`, `itemset`, IF (`Flags` & ?d, 1, 0) AS "heroic", IF(`InventoryType` = 15, 26, IF(`InventoryType` = 5, 20, `InventoryType`)) AS "slot" FROM item_template WHERE `itemset` > 0', ITEM_FLAG_HEROIC); + $pieces = DB::World()->selectAssoc('SELECT `itemset` AS ARRAY_KEY, `entry` AS ARRAY_KEY2, `entry`, `name`, `class`, `subclass`, `Quality`, `AllowableClass`, `ItemLevel`, `RequiredLevel`, `itemset`, IF (`Flags` & %i, 1, 0) AS "heroic", IF(`InventoryType` = 15, 26, IF(`InventoryType` = 5, 20, `InventoryType`)) AS "slot" FROM item_template WHERE `itemset` > 0', ITEM_FLAG_HEROIC); foreach ($sets as $setId => $setData) { @@ -272,7 +272,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript if (count($pieces[$setId] ?? []) < 2) { $row['cuFlags'] = CUSTOM_EXCLUDE_FOR_LISTVIEW; - DB::Aowow()->query('INSERT INTO ?_itemset (?#) VALUES (?a)', array_keys($row), array_values($row)); + DB::Aowow()->qry('INSERT INTO ::itemset %v', $row); CLI::write('[item set] '.str_pad('['.$setId.']', 7).CLI::bold($setData['name_loc0']).' has no associated items', CLI::LOG_INFO); continue; } @@ -294,7 +294,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript else if (in_array($data['slot'], [INVTYPE_WEAPON, INVTYPE_FINGER, INVTYPE_TRINKET])) $sorted[$k][-$data['slot']] = $data; // slot confict. If item is being sold, replace old item (imperfect solution :/) - else if (DB::World()->selectCell('SELECT SUM(`n`) FROM (SELECT COUNT(1) AS "n" FROM npc_vendor WHERE `item` = ?d UNION SELECT COUNT(1) AS "n" FROM game_event_npc_vendor WHERE `item` = ?d) x', $data['entry'], $data['entry'])) + else if (DB::World()->selectCell('SELECT SUM(`n`) FROM (SELECT COUNT(1) AS "n" FROM npc_vendor WHERE `item` = %i UNION SELECT COUNT(1) AS "n" FROM game_event_npc_vendor WHERE `item` = %i) x', $data['entry'], $data['entry'])) $sorted[$k][$data['slot']] = $data; } @@ -311,7 +311,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript if ($i++) $vRow['id'] = --$virtualId; - DB::Aowow()->query('INSERT INTO ?_itemset (?#) VALUES (?a)', array_keys($vRow), array_values($vRow)); + DB::Aowow()->qry('INSERT INTO ::itemset %v', $vRow); } } diff --git a/setup/tools/sqlgen/itemstats.ss.php b/setup/tools/sqlgen/itemstats.ss.php index 0b6cbec5..e1619581 100644 --- a/setup/tools/sqlgen/itemstats.ss.php +++ b/setup/tools/sqlgen/itemstats.ss.php @@ -11,7 +11,7 @@ if (!CLI) class ItemStatSetup extends ItemList { - public function __construct(int $start, int $limit, int $itemClass, array $ids, private bool $applyTriggered, private array $relEnchants, private array $relSpells) + public function __construct(int $start, int $limit, int $itemClass, private bool $applyTriggered, private array $relEnchants, private array $relSpells) { $this->queryOpts['i']['o'] = 'i.id ASC'; unset($this->queryOpts['is']); // do not reference the stats table we are going to write to @@ -22,9 +22,6 @@ class ItemStatSetup extends ItemList $limit ); - if ($ids) - $conditions[] = ['id', $ids]; - parent::__construct($conditions); } @@ -40,14 +37,14 @@ class ItemStatSetup extends ItemList if ($spellIds) // array_merge kills the keys { - $newSpells = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM ?_spell WHERE id IN (?a)', $spellIds); + $newSpells = DB::Aowow()->selectAssoc('SELECT *, id AS ARRAY_KEY FROM ::spell WHERE id IN %in', $spellIds); $this->relSpells = array_replace($this->relSpells, $newSpells); // include triggered spell to calculate nutritional values if ($this->applyTriggered) if ($t = array_filter(array_merge(array_column($newSpells, 'effect1TriggerSpell'), array_column($newSpells, 'effect2TriggerSpell'), array_column($newSpells, 'effect3TriggerSpell')))) if ($t = array_diff($t, array_keys($this->relSpells))) - $this->relSpells = array_replace($this->relSpells, DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM ?_spell WHERE id IN (?a)', $t)); + $this->relSpells = array_replace($this->relSpells, DB::Aowow()->selectAssoc('SELECT *, id AS ARRAY_KEY FROM ::spell WHERE id IN %in', $t)); } // fromItem: itemMods, spell, enchants from template - fromJson: calculated stats (feralAP, dps, ...) @@ -58,12 +55,9 @@ class ItemStatSetup extends ItemList if ($this->getField('class') == ITEM_CLASS_WEAPON) $stats += $shared + ($this->isRangedWeapon() ? ['rgddps' => 0, 'rgddmgmin' => 0, 'rgddmgmax' => 0, 'rgdspeed' => 0] : ['mledps' => 0, 'mledmgmin' => 0, 'mledmgmax' => 0, 'mlespeed' => 0]); else if ($this->getField('class') == ITEM_CLASS_ARMOR) - $stats += ['armorbonus' => 0]; //ArmorDamageModifier only valid on armor(?) + $stats += ['armorbonus' => 0]; //ArmorDamageModifier only valid on armor(%s) - // apply PK - $stats += ['type' => Type::ITEM, 'typeId' => $this->id]; - - DB::Aowow()->query('INSERT INTO ?_item_stats (?#) VALUES (?a)', array_keys($stats), array_values($stats)); + DB::Aowow()->qry('INSERT INTO ::item_stats %v', ['type' => Type::ITEM, 'typeId' => $this->id] + $stats); } } } @@ -82,9 +76,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript private function enchantment_stats(?int &$total = 0, ?int &$effective = 0) : array { - $enchants = DB::Aowow()->select('SELECT *, `id` AS ARRAY_KEY FROM dbc_spellitemenchantment'); + $enchants = DB::Aowow()->selectAssoc('SELECT *, `id` AS ARRAY_KEY FROM dbc_spellitemenchantment'); $spells = []; - $result = []; + $stats = []; $effective = 0; $total = count($enchants); @@ -94,21 +88,21 @@ CLISetup::registerSetup("sql", new class extends SetupScript $spells[] = $e['object'.$i]; if ($spells) - $this->relSpells = DB::Aowow()->select('SELECT *, id AS ARRAY_KEY FROM ?_spell WHERE id IN (?a)', $spells); + $this->relSpells = DB::Aowow()->selectAssoc('SELECT *, id AS ARRAY_KEY FROM ::spell WHERE id IN %in', $spells); foreach ($enchants as $eId => $e) - if ($result[$eId] = (new StatsContainer($this->relSpells))->fromEnchantment($e)->toJson(Stat::FLAG_ITEM | Stat::FLAG_SERVERSIDE)) + if ($stats = (new StatsContainer($this->relSpells))->fromEnchantment($e)->toJson(Stat::FLAG_ITEM | Stat::FLAG_SERVERSIDE)) { - DB::Aowow()->query('INSERT INTO ?_item_stats (?#) VALUES (?a)', array_merge(['type', 'typeId'], array_keys($result[$eId])), array_merge([Type::ENCHANTMENT, $eId], array_values($result[$eId]))); + DB::Aowow()->qry('INSERT INTO ::item_stats %v', ['type' => Type::ENCHANTMENT, 'typeId' => $eId] + $stats); $effective++; } return $enchants; } - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_item_stats'); + DB::Aowow()->qry('TRUNCATE ::item_stats'); CLI::write('[stats] - applying stats for enchantments'); @@ -130,7 +124,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript $offset = 0; while (true) { - $items = new ItemStatSetup($offset, CLISetup::SQL_BATCH, $itemClass, $ids, $applyTriggered, $enchStats, $this->relSpells); + $items = new ItemStatSetup($offset, CLISetup::SQL_BATCH, $itemClass, $applyTriggered, $enchStats, $this->relSpells); if ($items->error) break; diff --git a/setup/tools/sqlgen/mailtemplate.ss.php b/setup/tools/sqlgen/mailtemplate.ss.php index d2e17d1e..f3cdb5c5 100644 --- a/setup/tools/sqlgen/mailtemplate.ss.php +++ b/setup/tools/sqlgen/mailtemplate.ss.php @@ -18,16 +18,16 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['mailtemplate']; protected $worldDependency = ['achievement_reward', 'achievement_reward_locale', 'mail_loot_template']; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_mails'); + DB::Aowow()->qry('TRUNCATE ::mails'); // copy data over from dbc - DB::Aowow()->query('INSERT INTO ?_mails SELECT `id`, 0, `subject_loc0`, `subject_loc2`, `subject_loc3`, `subject_loc4`, `subject_loc6`, `subject_loc8`, `text_loc0`, `text_loc2`, `text_loc3`, `text_loc4`, `text_loc6`, `text_loc8`, 0 FROM dbc_mailtemplate'); + DB::Aowow()->qry('INSERT INTO ::mails SELECT `id`, 0, `subject_loc0`, `subject_loc2`, `subject_loc3`, `subject_loc4`, `subject_loc6`, `subject_loc8`, `text_loc0`, `text_loc2`, `text_loc3`, `text_loc4`, `text_loc6`, `text_loc8`, 0 FROM dbc_mailtemplate'); CLI::write('[mails] - loading data from achievement_reward'); - $acvMail = DB::World()->select( + $acvMail = DB::World()->selectAssoc( 'SELECT -ar.`ID`, 0, IFNULL(ar.`Subject`, "") AS "s0", IFNULL(arl2.`Subject`, "") AS "s2", IFNULL(arl3.`Subject`, "") AS "s3", IFNULL(arl4.`Subject`, "") AS "s4", IFNULL(arl6.`Subject`, "") AS "s6", IFNULL(arl8.`Subject`, "") AS "s8", IFNULL(ar.`Body`, "") AS "t0", IFNULL(arl2.`Body`, "") AS "t2", IFNULL(arl3.`Body`, "") AS "t3", IFNULL(arl4.`Body`, "") AS "t4", IFNULL(arl6.`Body`, "") AS "t6", IFNULL(arl8.`Body`, "") AS "t8", @@ -41,14 +41,15 @@ CLISetup::registerSetup("sql", new class extends SetupScript WHERE ar.`MailTemplateID` = 0 AND ar.`Body` <> ""' ); - DB::Aowow()->query('INSERT INTO ?_mails VALUES (?a)', array_values($acvMail)); + foreach ($acvMail as $am) + DB::Aowow()->qry('INSERT INTO ::mails VALUES %l', $am); CLI::write('[mails] - loading data from mail_loot_template'); // assume mails to only contain one single item, wich works for an unmodded installation $mlt = DB::World()->selectCol('SELECT `Entry` AS ARRAY_KEY, `Item` FROM mail_loot_template'); foreach ($mlt as $k => $v) - DB::Aowow()->query('UPDATE ?_mails SET `attachment` = ?d WHERE `id` = ?d', $v, $k); + DB::Aowow()->qry('UPDATE ::mails SET `attachment` = %i WHERE `id` = %i', $v, $k); return true; } diff --git a/setup/tools/sqlgen/objects.ss.php b/setup/tools/sqlgen/objects.ss.php index 66d5d77f..92ff9486 100644 --- a/setup/tools/sqlgen/objects.ss.php +++ b/setup/tools/sqlgen/objects.ss.php @@ -18,7 +18,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['lock']; protected $worldDependency = ['gameobject_template', 'gameobject_template_addon', 'gameobject_template_locale', 'gameobject_questitem']; - public function generate(array $ids = []) : bool + public function generate() : bool { $baseQuery = 'SELECT go.entry, @@ -63,33 +63,30 @@ CLISetup::registerSetup("sql", new class extends SetupScript LEFT JOIN gameobject_template_locale gtl6 ON go.entry = gtl6.entry AND gtl6.`locale` = "esES" LEFT JOIN gameobject_template_locale gtl8 ON go.entry = gtl8.entry AND gtl8.`locale` = "ruRU" LEFT JOIN gameobject_questitem gqi ON gqi.GameObjectEntry = go.entry - { WHERE go.entry IN (?a) } GROUP BY go.entry - LIMIT ?d, ?d'; + LIMIT %i, %i'; - DB::Aowow()->query('TRUNCATE ?_objects'); - DB::Aowow()->query('SET SESSION innodb_ft_enable_stopword = OFF'); + DB::Aowow()->qry('TRUNCATE ::objects'); + DB::Aowow()->qry('SET SESSION innodb_ft_enable_stopword = OFF'); $i = 0; - while ($objects = DB::World()->select($baseQuery, $ids ?: DBSIMPLE_SKIP, CLISetup::SQL_BATCH * $i, CLISetup::SQL_BATCH)) + while ($objects = DB::World()->selectAssoc($baseQuery, CLISetup::SQL_BATCH * $i, CLISetup::SQL_BATCH)) { CLI::write(' * batch #' . ++$i . ' (' . count($objects) . ')', CLI::LOG_BLANK, true, true); foreach ($objects as $object) - DB::Aowow()->query('INSERT INTO ?_objects VALUES (?a)', array_values($object)); + DB::Aowow()->qry('INSERT INTO ::objects VALUES %l', $object); } // apply typeCat and reqSkill depending on locks - DB::Aowow()->query( - 'UPDATE ?_objects o + DB::Aowow()->qry( + 'UPDATE ::objects o LEFT JOIN dbc_lock l ON l.id = IF(o.`type` = 3, lockId, null) SET typeCat = IF(`type` = 3 AND (l.properties1 = 1 OR l.properties2 = 1), -5, -- footlocker IF(`type` = 3 AND (l.properties1 = 2), -3, -- herb IF(`type` = 3 AND (l.properties1 = 3), -4, typeCat))), -- ore reqSkill = IF(`type` = 3 AND l.properties1 IN (1, 2, 3), IF(l.reqSkill1 > 1, l.reqSkill1, 1), - IF(`type` = 3 AND l.properties2 = 1, IF(l.reqSkill2 > 1, l.reqSkill2, 1), 0)) - { WHERE o.id IN (?a) }', - $ids ?: DBSIMPLE_SKIP + IF(`type` = 3 AND l.properties2 = 1, IF(l.reqSkill2 > 1, l.reqSkill2, 1), 0))', ); $this->reapplyCCFlags('objects', Type::OBJECT); diff --git a/setup/tools/sqlgen/pet.ss.php b/setup/tools/sqlgen/pet.ss.php index 5a6bbd32..d7aa96a0 100644 --- a/setup/tools/sqlgen/pet.ss.php +++ b/setup/tools/sqlgen/pet.ss.php @@ -21,13 +21,13 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $worldDependency = ['creature_template', 'creature']; protected $setupAfter = [['icons'], []]; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_pet'); + DB::Aowow()->qry('TRUNCATE ::pet'); // basic copy from creaturefamily.dbc - DB::Aowow()->query( - 'INSERT INTO ?_pet + DB::Aowow()->qry( + 'INSERT INTO ::pet SELECT f.`id`, `categoryEnumId`, 0, -- cuFlags @@ -43,28 +43,28 @@ CLISetup::registerSetup("sql", new class extends SetupScript 0, 0, 0, 0, -- spell[1-4] 0, 0, 0 -- armor, damage, health FROM dbc_creaturefamily f - LEFT JOIN ?_icons ic ON ic.`name_source` = LOWER(SUBSTRING_INDEX(f.`iconString`, "\\\\", -1)) + LEFT JOIN ::icons ic ON ic.`name_source` = LOWER(SUBSTRING_INDEX(f.`iconString`, "\\", -1)) WHERE `petTalentType` <> -1' ); // stats from craeture_template - $spawnInfo = DB::World()->query( + $spawnInfo = DB::World()->selectAssoc( 'SELECT ct.`family` AS ARRAY_KEY, MIN(ct.`minlevel`) AS "minLevel", MAX(ct.`maxlevel`) AS "maxLevel", - IF(ct.`type_flags` & ?d, 1, 0) AS "exotic" + IF(ct.`type_flags` & %i, 1, 0) AS "exotic" FROM creature_template ct JOIN creature c ON ct.`entry` = c.`id` - WHERE ct.`type_flags` & ?d + WHERE ct.`type_flags` & %i GROUP BY ct.`family`', NPC_TYPEFLAG_EXOTIC_PET, NPC_TYPEFLAG_TAMEABLE ); foreach ($spawnInfo as $id => $info) - DB::Aowow()->query('UPDATE ?_pet SET ?a WHERE id = ?d', $info, $id); + DB::Aowow()->qry('UPDATE ::pet SET %a WHERE id = %i', $info, $id); // add petFamilyModifier to health, mana, dmg - DB::Aowow()->query( - 'UPDATE ?_pet p, + DB::Aowow()->qry( + 'UPDATE ::pet p, dbc_skilllineability sla, dbc_spell s SET `armor` = s.`effect2BasePoints` + s.`effect2DieSides`, @@ -76,13 +76,13 @@ CLISetup::registerSetup("sql", new class extends SetupScript ); // assign pet spells - $pets = DB::Aowow()->select( + $pets = DB::Aowow()->selectAssoc( 'SELECT p.`id`, MAX(s.`id`) AS "spell" FROM dbc_skilllineability sla - JOIN ?_pet p ON p.`skillLineId` = sla.`skillLineId` + JOIN ::pet p ON p.`skillLineId` = sla.`skillLineId` JOIN dbc_spell s ON sla.`spellId` = s.`id` LEFT OUTER JOIN dbc_talent t ON s.`id` = t.`rank1` - WHERE (s.`attributes0` & ?d) = 0 AND t.`id` IS NULL + WHERE (s.`attributes0` & %i) = 0 AND t.`id` IS NULL GROUP BY s.`name_loc0`, p.`id`', SPELL_ATTR0_PASSIVE ); @@ -97,7 +97,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript } foreach ($petSpells as $petId => $row) - DB::Aowow()->query('UPDATE ?_pet SET ?a WHERE `id` = ?d', $row, $petId); + DB::Aowow()->qry('UPDATE ::pet SET %a WHERE `id` = %i', $row, $petId); $this->reapplyCCFlags('pet', Type::PET); diff --git a/setup/tools/sqlgen/quests.ss.php b/setup/tools/sqlgen/quests.ss.php index 6f386a03..475f5d0a 100644 --- a/setup/tools/sqlgen/quests.ss.php +++ b/setup/tools/sqlgen/quests.ss.php @@ -20,7 +20,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['questxp', 'questfactionreward']; protected $worldDependency = ['quest_template', 'quest_template_addon', 'quest_template_locale', 'game_event', 'game_event_seasonal_questrelation', 'quest_request_items', 'quest_request_items_locale', 'quest_offer_reward', 'quest_offer_reward_locale', 'disables']; - public function generate(array $ids = []) : bool + public function generate() : bool { $baseQuery = 'SELECT q.ID, @@ -113,19 +113,18 @@ CLISetup::registerSetup("sql", new class extends SetupScript LEFT JOIN quest_template_addon qa ON q.ID = qa.ID LEFT JOIN game_event_seasonal_questrelation gesqr ON gesqr.questId = q.ID LEFT JOIN disables d ON d.entry = q.ID AND d.sourceType = 1 - { WHERE q.Id IN (?a) } - LIMIT ?d, ?d'; + LIMIT %i, %i'; - DB::Aowow()->query('TRUNCATE ?_quests'); - DB::Aowow()->query('SET SESSION innodb_ft_enable_stopword = OFF'); + DB::Aowow()->qry('TRUNCATE ::quests'); + DB::Aowow()->qry('SET SESSION innodb_ft_enable_stopword = OFF'); $i = 0; - while ($quests = DB::World()->select($baseQuery, $ids ?: DBSIMPLE_SKIP, CLISetup::SQL_BATCH * $i, CLISetup::SQL_BATCH)) + while ($quests = DB::World()->selectAssoc($baseQuery, CLISetup::SQL_BATCH * $i, CLISetup::SQL_BATCH)) { CLI::write(' * batch #' . ++$i . ' (' . count($quests) . ')', CLI::LOG_BLANK, true, true); foreach ($quests as $quest) - DB::Aowow()->query('INSERT INTO ?_quests VALUES (?a)', array_values($quest)); + DB::Aowow()->qry('INSERT INTO ::quests VALUES %l', $quest); } @@ -141,14 +140,13 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write(' * unpacking XP rewards (1/4)', CLI::LOG_BLANK, true, true); // unpack XP-reward - DB::Aowow()->query( - 'UPDATE ?_quests q, dbc_questxp xp + DB::Aowow()->qry( + 'UPDATE ::quests q, dbc_questxp xp SET `rewardXP` = (CASE `rewardXP` WHEN 0 THEN xp.`Field1` WHEN 1 THEN xp.`Field2` WHEN 2 THEN xp.`Field3` WHEN 3 THEN xp.`Field4` WHEN 4 THEN xp.`Field5` WHEN 5 THEN xp.`Field6` WHEN 6 THEN xp.`Field7` WHEN 7 THEN xp.`Field8` WHEN 8 THEN xp.`Field9` WHEN 9 THEN xp.`Field10` ELSE 0 END) - WHERE xp.`id` = q.`level` { AND q.`id` IN (?a) }', - $ids ?: DBSIMPLE_SKIP + WHERE xp.`id` = q.`level`', ); @@ -156,46 +154,45 @@ CLISetup::registerSetup("sql", new class extends SetupScript // unpack Rep-rewards for ($i = 1; $i < 6; $i++) - DB::Aowow()->query( - 'UPDATE ?_quests q - LEFT JOIN dbc_questfactionreward rep ON rep.`id` = IF(rewardFactionValue?d > 0, 1, 2) - SET rewardFactionValue?d = (CASE ABS(rewardFactionValue?d) + DB::Aowow()->qry( + 'UPDATE ::quests q + LEFT JOIN dbc_questfactionreward rep ON rep.`id` = IF(rewardFactionValue%i > 0, 1, 2) + SET rewardFactionValue%i = (CASE ABS(rewardFactionValue%i) WHEN 0 THEN rep.`Field1` WHEN 1 THEN rep.`Field2` WHEN 2 THEN rep.`Field3` WHEN 3 THEN rep.`Field4` WHEN 4 THEN rep.`Field5` WHEN 5 THEN rep.`Field6` WHEN 6 THEN rep.`Field7` WHEN 7 THEN rep.`Field8` WHEN 8 THEN rep.`Field9` WHEN 9 THEN rep.`Field10` ELSE 0 END) - WHERE ABS(rewardFactionValue?d) BETWEEN 1 AND 10 { AND q.`id` IN (?a) }', + WHERE ABS(rewardFactionValue%i) BETWEEN 1 AND 10', $i, $i, $i, $i, - $ids ?: DBSIMPLE_SKIP ); CLI::write(' * flagging quests series (3/4)', CLI::LOG_BLANK, true, true); // set series flags - DB::Aowow()->query( - 'UPDATE ?_quests q - LEFT JOIN ?_quests q2 ON q2.`NextQuestIdChain` = q.id - SET q.`cuFlags` = q.`cuFlags` | ?d + DB::Aowow()->qry( + 'UPDATE ::quests q + LEFT JOIN ::quests q2 ON q2.`NextQuestIdChain` = q.id + SET q.`cuFlags` = q.`cuFlags` | %i WHERE q.`NextQuestIdChain` > 0 AND q2.`id` IS NULL', QUEST_CU_FIRST_SERIES | QUEST_CU_PART_OF_SERIES ); - DB::Aowow()->query( - 'UPDATE ?_quests q - JOIN ?_quests q2 ON q2.`NextQuestIdChain` = q.id - SET q.`cuFlags` = q.`cuFlags` | ?d + DB::Aowow()->qry( + 'UPDATE ::quests q + JOIN ::quests q2 ON q2.`NextQuestIdChain` = q.id + SET q.`cuFlags` = q.`cuFlags` | %i WHERE q.`NextQuestIdChain` = 0', QUEST_CU_LAST_SERIES | QUEST_CU_PART_OF_SERIES ); - DB::Aowow()->query('UPDATE ?_quests SET `cuFlags` = `cuFlags` | ?d WHERE `NextQuestIdChain` > 0', QUEST_CU_PART_OF_SERIES); + DB::Aowow()->qry('UPDATE ::quests SET `cuFlags` = `cuFlags` | %i WHERE `NextQuestIdChain` > 0', QUEST_CU_PART_OF_SERIES); CLI::write(' * applying fixes (4/4)', CLI::LOG_BLANK, true, true); // fix questSorts for instance quests foreach (Game::$questSortFix as $child => $parent) - DB::Aowow()->query('UPDATE ?_quests SET `questSortId` = ?d WHERE `questSortIdBak` = ?d', $parent, $child); + DB::Aowow()->qry('UPDATE ::quests SET `questSortId` = %i WHERE `questSortIdBak` = %i', $parent, $child); // move quests linked to holidays into appropirate quests-sorts. create dummy sorts as needed @@ -209,20 +206,20 @@ CLISetup::registerSetup("sql", new class extends SetupScript foreach ($holidaySorts as $hId => $sort) if (!empty($eventSet[$hId])) - DB::Aowow()->query('UPDATE ?_quests SET `questSortId` = ?d WHERE `eventId` = ?d{ AND `id` IN (?a)}', $sort, $eventSet[$hId], $ids ?: DBSIMPLE_SKIP); + DB::Aowow()->qry('UPDATE ::quests SET `questSortId` = %i WHERE `eventId` = %i', $sort, $eventSet[$hId]); // 'special' special cases // fishing quests to stranglethorn extravaganza - DB::Aowow()->query('UPDATE ?_quests SET `questSortId` = ?d WHERE `id` IN (?a){ AND `id` IN (?a)}', -101, [8228, 8229], $ids ?: DBSIMPLE_SKIP); + DB::Aowow()->qry('UPDATE ::quests SET `questSortId` = %i WHERE `id` IN %in', -101, [8228, 8229]); // dungeon quests to Misc/Dungeon Finder - DB::Aowow()->query('UPDATE ?_quests SET `questSortId` = ?d WHERE (`specialFlags` & ?d OR `id` IN (?a)){ AND `id` IN (?a)}', -1010, QUEST_FLAG_SPECIAL_DUNGEON_FINDER, [24789, 24791, 24923], $ids ?: DBSIMPLE_SKIP); + DB::Aowow()->qry('UPDATE ::quests SET `questSortId` = %i WHERE (`specialFlags` & %i OR `id` IN %in)', -1010, QUEST_FLAG_SPECIAL_DUNGEON_FINDER, [24789, 24791, 24923]); // flag internal/unsued quests as unsearchable - DB::Aowow()->query( - 'UPDATE ?_quests - SET `cuFlags` = `cuFlags` | ?d + DB::Aowow()->qry( + 'UPDATE ::quests + SET `cuFlags` = `cuFlags` | %i WHERE `name_loc0` LIKE "%<%" OR `name_loc0` LIKE "%[%" OR `name_loc0` LIKE "%deprecated%" OR `name_loc0` LIKE "%unused%" OR diff --git a/setup/tools/sqlgen/questsstartend.ss.php b/setup/tools/sqlgen/questsstartend.ss.php index bdee3959..da847eef 100644 --- a/setup/tools/sqlgen/questsstartend.ss.php +++ b/setup/tools/sqlgen/questsstartend.ss.php @@ -17,7 +17,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $worldDependency = ['creature_queststarter', 'creature_questender', 'game_event_creature_quest', 'gameobject_queststarter', 'gameobject_questender', 'game_event_gameobject_quest', 'item_template']; - public function generate(array $ids = []) : bool + public function generate() : bool { $query['NPC'] = 'SELECT 1 AS `type`, `id` AS `typeId`, `quest` AS `questId`, 1 AS `method`, 0 AS `eventId` FROM creature_queststarter UNION @@ -31,19 +31,19 @@ CLISetup::registerSetup("sql", new class extends SetupScript $query['Item'] = 'SELECT 3 AS `type`, `entry` AS `typeId`, `startquest` AS `questId`, 1 AS `method`, 0 AS `eventId` FROM item_template WHERE `startquest` <> 0'; - DB::Aowow()->query('TRUNCATE ?_quests_startend'); + DB::Aowow()->qry('TRUNCATE ::quests_startend'); foreach ($query as $n => $q) { CLI::write(' - ' . $n . ' start/end-points', CLI::LOG_BLANK, true, true); - $data = DB::World()->select($q); + $data = DB::World()->selectAssoc($q); foreach ($data as $d) - DB::Aowow()->query('INSERT INTO ?_quests_startend (?#) VALUES (?a) ON DUPLICATE KEY UPDATE `method` = `method` | ?d, `eventId` = IF(`eventId` = 0, ?d, `eventId`)', array_keys($d), array_values($d), $d['method'], $d['eventId']); + DB::Aowow()->qry('INSERT INTO ::quests_startend %v ON DUPLICATE KEY UPDATE `method` = `method` | %i, `eventId` = IF(`eventId` = 0, %i, `eventId`)', $d, $d['method'], $d['eventId']); } // update quests without start as unavailable - Db::Aowow()->query('UPDATE ?_quests q LEFT JOIN ?_quests_startend qse ON qse.`questId` = q.`id` AND qse.`method` & 1 SET q.`cuFlags` = q.`cuFlags` | ?d WHERE qse.`questId` IS NULL', CUSTOM_UNAVAILABLE); + DB::Aowow()->qry('UPDATE ::quests q LEFT JOIN ::quests_startend qse ON qse.`questId` = q.`id` AND qse.`method` & 1 SET q.`cuFlags` = q.`cuFlags` | %i WHERE qse.`questId` IS NULL', CUSTOM_UNAVAILABLE); return true; } diff --git a/setup/tools/sqlgen/races.ss.php b/setup/tools/sqlgen/races.ss.php index 9927a146..92370294 100644 --- a/setup/tools/sqlgen/races.ss.php +++ b/setup/tools/sqlgen/races.ss.php @@ -20,23 +20,23 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $setupAfter = [['icons'], []]; protected $dbcSourceFiles = ['chrraces', 'charbaseinfo']; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_races'); - DB::Aowow()->query( - 'INSERT INTO ?_races + DB::Aowow()->qry('TRUNCATE ::races'); + DB::Aowow()->qry( + 'INSERT INTO ::races SELECT `id`, 0, `flags`, 0, `factionId`, 0, 0, `baseLanguage`, IF(`side` = 2, 0, `side` + 1), `fileString`, 0, 0, `name_loc0`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc6`, `name_loc8`, `expansion` FROM dbc_chrraces' ); // collect iconIds - DB::Aowow()->query('UPDATE ?_races r, ?_icons i0, ?_icons i1 SET r.`iconId0` = i0.`id`, r.`iconId1` = i1.`id` WHERE i0.`name_source` = CONCAT("race_", LOWER(r.`fileString`), "_male") AND i1.`name_source` = CONCAT("race_", LOWER(r.`fileString`), "_female")'); + DB::Aowow()->qry('UPDATE ::races r, ::icons i0, ::icons i1 SET r.`iconId0` = i0.`id`, r.`iconId1` = i1.`id` WHERE i0.`name_source` = CONCAT("race_", LOWER(r.`fileString`), "_male") AND i1.`name_source` = CONCAT("race_", LOWER(r.`fileString`), "_female")'); // add classMask - DB::Aowow()->query('UPDATE ?_races r JOIN (SELECT BIT_OR(1 << (`classId` - 1)) AS "classMask", `raceId` FROM dbc_charbaseinfo GROUP BY `raceId`) cbi ON cbi.`raceId` = r.id SET r.`classMask` = cbi.`classMask`'); + DB::Aowow()->qry('UPDATE ::races r JOIN (SELECT BIT_OR(1 << (`classId` - 1)) AS "classMask", `raceId` FROM dbc_charbaseinfo GROUP BY `raceId`) cbi ON cbi.`raceId` = r.id SET r.`classMask` = cbi.`classMask`'); // add cuFlags - DB::Aowow()->query('UPDATE ?_races SET `cuFlags` = ?d WHERE `flags` & ?d', CUSTOM_EXCLUDE_FOR_LISTVIEW, 0x1); + DB::Aowow()->qry('UPDATE ::races SET `cuFlags` = %i WHERE `flags` & %i', CUSTOM_EXCLUDE_FOR_LISTVIEW, 0x1); $this->reapplyCCFlags('races', Type::CHR_RACE); diff --git a/setup/tools/sqlgen/shapeshiftforms.ss.php b/setup/tools/sqlgen/shapeshiftforms.ss.php index eeb53455..0c31afe7 100644 --- a/setup/tools/sqlgen/shapeshiftforms.ss.php +++ b/setup/tools/sqlgen/shapeshiftforms.ss.php @@ -19,11 +19,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['spellshapeshiftform']; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_shapeshiftforms'); - DB::Aowow()->query( - 'INSERT INTO ?_shapeshiftforms + DB::Aowow()->qry('TRUNCATE ::shapeshiftforms'); + DB::Aowow()->qry( + 'INSERT INTO ::shapeshiftforms SELECT id, flags, creatureType, displayIdA, displayIdH, spellId1, spellId2, spellId3, spellId4, spellId5, spellId6, spellId7, spellId8, IF(name_loc0 = "", IF(name_loc2 = "", IF(name_loc3 = "", IF(name_loc4 = "", IF(name_loc6 = "", IF(name_loc8 = "", "???", name_loc8), name_loc6), name_loc4), name_loc3), name_loc2), name_loc0) diff --git a/setup/tools/sqlgen/skillline.ss.php b/setup/tools/sqlgen/skillline.ss.php index 2c5c9200..d0433cce 100644 --- a/setup/tools/sqlgen/skillline.ss.php +++ b/setup/tools/sqlgen/skillline.ss.php @@ -20,41 +20,41 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['skillline', 'spell', 'skilllineability']; protected $setupAfter = [['icons'], []]; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_skillline'); - DB::Aowow()->query( - 'INSERT INTO ?_skillline + DB::Aowow()->qry('TRUNCATE ::skillline'); + DB::Aowow()->qry( + 'INSERT INTO ::skillline SELECT id, categoryId, 0, categoryId, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8, description_loc0, description_loc2, description_loc3, description_loc4, description_loc6, description_loc8, 0, iconId, 0, 0, "" FROM dbc_skillline' ); // categorization - DB::Aowow()->query('UPDATE ?_skillline SET typeCat = -5 WHERE id = 777 OR (categoryId = 9 AND id NOT IN (356, 129, 185, 142, 155))'); - DB::Aowow()->query('UPDATE ?_skillline SET typeCat = -4 WHERE categoryId = 9 AND name_loc0 LIKE "%racial%"'); - DB::Aowow()->query('UPDATE ?_skillline SET typeCat = -6 WHERE id IN (778, 788, 758) OR (categoryId = 7 AND name_loc0 LIKE "%pet%")'); + DB::Aowow()->qry('UPDATE ::skillline SET typeCat = -5 WHERE id = 777 OR (categoryId = 9 AND id NOT IN (356, 129, 185, 142, 155))'); + DB::Aowow()->qry('UPDATE ::skillline SET typeCat = -4 WHERE categoryId = 9 AND name_loc0 LIKE "%racial%"'); + DB::Aowow()->qry('UPDATE ::skillline SET typeCat = -6 WHERE id IN (778, 788, 758) OR (categoryId = 7 AND name_loc0 LIKE "%pet%")'); // more complex fixups - DB::Aowow()->query('UPDATE ?_skillline SET name_loc8 = REPLACE(name_loc8, " - ", ": ") WHERE categoryId = 7 OR id IN (758, 788)'); - DB::Aowow()->query('UPDATE ?_skillline SET cuFlags = ?d WHERE id IN (?a)', CUSTOM_EXCLUDE_FOR_LISTVIEW, [142, 148, 149, 150, 152, 155, 183, 533, 553, 554, 713, 769]); + DB::Aowow()->qry('UPDATE ::skillline SET name_loc8 = REPLACE(name_loc8, " - ", ": ") WHERE categoryId = 7 OR id IN (758, 788)'); + DB::Aowow()->qry('UPDATE ::skillline SET cuFlags = %i WHERE id IN %in', CUSTOM_EXCLUDE_FOR_LISTVIEW, [142, 148, 149, 150, 152, 155, 183, 533, 553, 554, 713, 769]); // apply icons - DB::Aowow()->query('UPDATE ?_skillline sl, ?_icons ic, dbc_spellicon si SET sl.iconId = ic.id WHERE sl.iconIdBak = si.id AND ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1))'); - DB::Aowow()->query( - 'UPDATE ?_skillline sl, + DB::Aowow()->qry('UPDATE ::skillline sl, ::icons ic, dbc_spellicon si SET sl.iconId = ic.id WHERE sl.iconIdBak = si.id AND ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\", -1))'); + DB::Aowow()->qry( + 'UPDATE ::skillline sl, dbc_spell s, dbc_skilllineability sla, - ?_icons ic, + ::icons ic, dbc_spellicon si SET sl.iconId = ic.id WHERE (s.effect1Id IN (25, 26, 40) OR s.effect2Id = 60) AND - ic.name_source = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1)) AND + ic.name_source = LOWER(SUBSTRING_INDEX(si.iconPath, "\\", -1)) AND s.iconId = si.id AND sla.spellId = s.id AND sl.id = sla.skillLineId' ); - DB::Aowow()->query('UPDATE ?_skillline sl, ?_icons ic SET sl.iconId = ic.id WHERE ic.name = ? AND sl.id = ?d', 'inv_misc_pelt_wolf_01', 393); - DB::Aowow()->query('UPDATE ?_skillline sl, ?_icons ic SET sl.iconId = ic.id WHERE ic.name = ? AND sl.id = ?d', 'inv_misc_key_03', 633); + DB::Aowow()->qry('UPDATE ::skillline sl, ::icons ic SET sl.iconId = ic.id WHERE ic.name = %s AND sl.id = %i', 'inv_misc_pelt_wolf_01', 393); + DB::Aowow()->qry('UPDATE ::skillline sl, ::icons ic SET sl.iconId = ic.id WHERE ic.name = %s AND sl.id = %i', 'inv_misc_key_03', 633); $this->reapplyCCFlags('skillline', Type::SKILL); diff --git a/setup/tools/sqlgen/sounds.ss.php b/setup/tools/sqlgen/sounds.ss.php index 84cb2b7b..c7be95e7 100644 --- a/setup/tools/sqlgen/sounds.ss.php +++ b/setup/tools/sqlgen/sounds.ss.php @@ -30,7 +30,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript 'material', 'itemgroupsounds', 'itemdisplayinfo', 'weaponimpactsounds', 'itemsubclass', 'weaponswingsounds2' /*, 'sheathesoundlookups' data is redundant with material..? */ ); - public function generate(array $ids = []) : bool + public function generate() : bool { /* okay, here's the thing. WMOAreaTable.dbc references WMO-files to get its position in the world (AreTable) and has sparse information on the related AreaTables themself. @@ -67,15 +67,15 @@ CLISetup::registerSetup("sql", new class extends SetupScript `file6` AS `soundFile6`, `file7` AS `soundFile7`, `file8` AS `soundFile8`, `file9` AS `soundFile9`, `file10` AS `soundFile10`, `path`, `flags` FROM dbc_soundentries - LIMIT ?d, ?d'; + LIMIT %i, %i'; - DB::Aowow()->query('TRUNCATE ?_sounds'); - DB::Aowow()->query('TRUNCATE ?_sounds_files'); + DB::Aowow()->qry('TRUNCATE ::sounds'); + DB::Aowow()->qry('TRUNCATE ::sounds_files'); $soundFileIdx = 0; $soundIndex = []; $j = 0; - while ($sounds = DB::Aowow()->select($query, $j * CLISetup::SQL_BATCH, CLISetup::SQL_BATCH)) + while ($sounds = DB::Aowow()->selectAssoc($query, $j * CLISetup::SQL_BATCH, CLISetup::SQL_BATCH)) { CLI::write('[sound] * batch #' . ++$j . ' (' . count($sounds) . ')', CLI::LOG_BLANK, true, true); @@ -108,7 +108,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript { $soundIndex[$nicePath] = ++$soundFileIdx; - $fileSets[] = [$soundFileIdx, $s['soundFile'.$i], $s['path'], SOUND_TYPE_OGG]; + $fileSets['id'][] = $soundFileIdx; + $fileSets['file'][] = $s['soundFile'.$i]; + $fileSets['path'][] = $s['path']; + $fileSets['type'][] = SOUND_TYPE_OGG; + $s['soundFile'.$i] = $soundFileIdx; } // mp3 .. keep as is @@ -116,7 +120,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript { $soundIndex[$nicePath] = ++$soundFileIdx; - $fileSets[] = [$soundFileIdx, $s['soundFile'.$i], $s['path'], SOUND_TYPE_MP3]; + $fileSets['id'][] = $soundFileIdx; + $fileSets['file'][] = $s['soundFile'.$i]; + $fileSets['path'][] = $s['path']; + $fileSets['type'][] = SOUND_TYPE_MP3; + $s['soundFile'.$i] = $soundFileIdx; } // i call bullshit @@ -137,14 +145,15 @@ CLISetup::registerSetup("sql", new class extends SetupScript continue; } else if ($fileSets) - DB::Aowow()->query('INSERT INTO ?_sounds_files VALUES (?a)', array_values($fileSets)); + DB::Aowow()->qry('INSERT INTO ::sounds_files %m', $fileSets); unset($s['path']); $groupSets[] = array_values($s); } - DB::Aowow()->query('INSERT INTO ?_sounds VALUES (?a)', array_values($groupSets)); + foreach ($groupSets as $gs) + DB::Aowow()->qry('INSERT INTO ::sounds VALUES %l', $gs); } @@ -154,9 +163,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[sound] - linking to race'); - DB::Aowow()->query('TRUNCATE ?_races_sounds'); - DB::Aowow()->query( - 'INSERT IGNORE INTO ?_races_sounds + DB::Aowow()->qry('TRUNCATE ::races_sounds'); + DB::Aowow()->qry( + 'INSERT IGNORE INTO ::races_sounds SELECT `raceId`, `soundIdMale`, 1 FROM dbc_vocaluisounds WHERE `soundIdMale` <> `soundIdFemale` AND `soundIdMale` > 0 UNION SELECT `raceId`, `soundIdFemale`, 2 FROM dbc_vocaluisounds WHERE `soundIdMale` <> `soundIdFemale` AND `soundIdFemale` > 0' ); @@ -168,8 +177,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[sound] - linking to emotes'); - DB::Aowow()->query('TRUNCATE ?_emotes_sounds'); - DB::Aowow()->query('INSERT IGNORE INTO ?_emotes_sounds SELECT `emotesTextId`, `raceId`, `gender` + 1, `soundId` FROM dbc_emotestextsound'); + DB::Aowow()->qry('TRUNCATE ::emotes_sounds'); + DB::Aowow()->qry('INSERT IGNORE INTO ::emotes_sounds SELECT `emotesTextId`, `raceId`, `gender` + 1, `soundId` FROM dbc_emotestextsound'); /*******************/ @@ -184,9 +193,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript // * customattack2 through 3 // in case of conflicting data CreatureDisplayInfo overrides CreatureModelData (seems to be more specialized (Thral > MaleOrc / Maiden > FemaleTitan)) - DB::Aowow()->query('TRUNCATE ?_creature_sounds'); - DB::Aowow()->query( - 'INSERT INTO ?_creature_sounds + DB::Aowow()->qry('TRUNCATE ::creature_sounds'); + DB::Aowow()->qry( + 'INSERT INTO ::creature_sounds SELECT cdi.`id`, GREATEST(IFNULL(ns.`greetSoundId`, 0), 0), GREATEST(IFNULL(ns.`byeSoundId`, 0), 0), @@ -236,9 +245,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript // * missile and impactarea not in js // * ready, castertargeting, casterstate and targetstate not in dbc - DB::Aowow()->query('TRUNCATE ?_spell_sounds'); - DB::Aowow()->query( - 'INSERT INTO ?_spell_sounds + DB::Aowow()->qry('TRUNCATE ::spell_sounds'); + DB::Aowow()->qry( + 'INSERT INTO ::spell_sounds SELECT sv.`id`, GREATEST(`animationSoundId`, 0), 0, -- ready @@ -282,9 +291,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript // omiting data from WMOAreaTable, as its at the moment impossible to link to actual zones - DB::Aowow()->query('TRUNCATE ?_zones_sounds'); - DB::Aowow()->query( - 'INSERT INTO ?_zones_sounds (`id`, `ambienceDay`, `ambienceNight`, `musicDay`, `musicNight`, `intro`, `worldStateId`, `worldStateValue`) + DB::Aowow()->qry('TRUNCATE ::zones_sounds'); + DB::Aowow()->qry( + 'INSERT INTO ::zones_sounds (`id`, `ambienceDay`, `ambienceNight`, `musicDay`, `musicNight`, `intro`, `worldStateId`, `worldStateValue`) SELECT a.`id`, IFNULL(sa1.`soundIdDay`, 0), IFNULL(sa1.`soundIdNight`, 0), @@ -311,13 +320,13 @@ CLISetup::registerSetup("sql", new class extends SetupScript LEFT JOIN dbc_soundambience sa2 ON sa2.`id` = wszs.`soundAmbienceId` LEFT JOIN dbc_zonemusic zm2 ON zm2.`id` = wszs.`zoneMusicId` LEFT JOIN dbc_zoneintromusictable zimt2 ON zimt2.`id` = wszs.`zoneIntroMusicId` - WHERE wszs.`zoneMusicId` > 0 AND (wszs.`areaId` OR wszs.`wmoAreaId` IN (?a))', + WHERE wszs.`zoneMusicId` > 0 AND (wszs.`areaId` OR wszs.`wmoAreaId` IN %in)', array_keys($worldStateZoneSoundFix) ); // apply post-fix foreach ($worldStateZoneSoundFix as $old => $new) - DB::Aowow()->query('UPDATE ?_zones_sounds SET `id` = ?d WHERE `id` = ?d', $new, $old); + DB::Aowow()->qry('UPDATE ::zones_sounds SET `id` = %i WHERE `id` = %i', $new, $old); /***************/ @@ -326,8 +335,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[sound] - linking to items'); - DB::Aowow()->query( - 'UPDATE ?_items i + DB::Aowow()->qry( + 'UPDATE ::items i LEFT JOIN dbc_itemdisplayinfo idi ON idi.`id` = i.`displayId` LEFT JOIN dbc_itemgroupsounds igs ON igs.`id` = idi.`groupSoundId` LEFT JOIN dbc_material m ON m.`id` = i.`material` @@ -338,22 +347,22 @@ CLISetup::registerSetup("sql", new class extends SetupScript i.`unsheatheSoundId` = IFNULL(m.`unsheatheSoundId`, 0)' ); - DB::Aowow()->query('TRUNCATE ?_items_sounds'); + DB::Aowow()->qry('TRUNCATE ::items_sounds'); $fields = ['hit', 'crit']; foreach ($fields as $f) for ($i = 1; $i <= 10; $i++) - DB::Aowow()->query( - 'INSERT INTO ?_items_sounds - SELECT ?#, (1 << wis.`subClass`) + DB::Aowow()->qry( + 'INSERT INTO ::items_sounds + SELECT %n, (1 << wis.`subClass`) FROM dbc_weaponimpactsounds wis - WHERE ?# > 0 + WHERE %n > 0 ON DUPLICATE KEY UPDATE `subClassMask` = `subClassMask` | (1 << wis.`subClass`)', $f.$i, $f.$i ); - DB::Aowow()->query( - 'INSERT INTO ?_items_sounds + DB::Aowow()->qry( + 'INSERT INTO ::items_sounds SELECT wss.`soundId`, (1 << isc.`subClass`) FROM dbc_itemsubclass isc JOIN dbc_weaponswingsounds2 wss ON wss.`weaponSize` = isc.`weaponSize` @@ -368,9 +377,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[sound] - linking to screen effects'); - DB::Aowow()->query('TRUNCATE ?_screeneffect_sounds'); - DB::Aowow()->query( - 'INSERT INTO ?_screeneffect_sounds + DB::Aowow()->qry('TRUNCATE ::screeneffect_sounds'); + DB::Aowow()->qry( + 'INSERT INTO ::screeneffect_sounds SELECT se.`id`, se.`name`, IFNULL(sa.`soundIdDay`, 0), IFNULL(sa.`soundIdNight`, 0), IFNULL(zm.`soundIdDay`, 0), IFNULL(zm.`soundIdNight`, 0) FROM dbc_screeneffect se LEFT JOIN dbc_soundambience sa ON se.`soundAmbienceId` = sa.`id` diff --git a/setup/tools/sqlgen/source.ss.php b/setup/tools/sqlgen/source.ss.php index d68a5aeb..be0ccd0c 100644 --- a/setup/tools/sqlgen/source.ss.php +++ b/setup/tools/sqlgen/source.ss.php @@ -41,34 +41,34 @@ CLISetup::registerSetup("sql", new class extends SetupScript 194326 => 194327 ); - public function generate(array $ids = []) : bool + public function generate() : bool { /*********************************/ /* resolve difficulty dummy NPCS */ /*********************************/ - $this->dummyNPCs = DB::Aowow()->select( - 'SELECT `difficultyEntry1` AS ARRAY_KEY, 2 AS "0", `id` AS "1" FROM ?_creature WHERE `difficultyEntry1` > 0 UNION - SELECT `difficultyEntry2` AS ARRAY_KEY, 4 AS "0", `id` AS "1" FROM ?_creature WHERE `difficultyEntry2` > 0 UNION - SELECT `difficultyEntry3` AS ARRAY_KEY, 8 AS "0", `id` AS "1" FROM ?_creature WHERE `difficultyEntry3` > 0' + $this->dummyNPCs = DB::Aowow()->selectAssoc( + 'SELECT `difficultyEntry1` AS ARRAY_KEY, 2 AS "0", `id` AS "1" FROM ::creature WHERE `difficultyEntry1` > 0 UNION + SELECT `difficultyEntry2` AS ARRAY_KEY, 4 AS "0", `id` AS "1" FROM ::creature WHERE `difficultyEntry2` > 0 UNION + SELECT `difficultyEntry3` AS ARRAY_KEY, 8 AS "0", `id` AS "1" FROM ::creature WHERE `difficultyEntry3` > 0' ); - $this->dummyGOs = DB::Aowow()->select( - 'SELECT `normal10` AS ARRAY_KEY, 1 AS "0", `normal10` AS "1", `mapType` AS "2" FROM ?_objectdifficulty WHERE `normal10` > 0 UNION - SELECT `normal25` AS ARRAY_KEY, 2 AS "0", `normal10` AS "1", `mapType` AS "2" FROM ?_objectdifficulty WHERE `normal25` > 0 UNION - SELECT `heroic10` AS ARRAY_KEY, 4 AS "0", `normal10` AS "1", `mapType` AS "2" FROM ?_objectdifficulty WHERE `heroic10` > 0 UNION - SELECT `heroic25` AS ARRAY_KEY, 8 AS "0", `normal10` AS "1", `mapType` AS "2" FROM ?_objectdifficulty WHERE `heroic25` > 0' + $this->dummyGOs = DB::Aowow()->selectAssoc( + 'SELECT `normal10` AS ARRAY_KEY, 1 AS "0", `normal10` AS "1", `mapType` AS "2" FROM ::objectdifficulty WHERE `normal10` > 0 UNION + SELECT `normal25` AS ARRAY_KEY, 2 AS "0", `normal10` AS "1", `mapType` AS "2" FROM ::objectdifficulty WHERE `normal25` > 0 UNION + SELECT `heroic10` AS ARRAY_KEY, 4 AS "0", `normal10` AS "1", `mapType` AS "2" FROM ::objectdifficulty WHERE `heroic10` > 0 UNION + SELECT `heroic25` AS ARRAY_KEY, 8 AS "0", `normal10` AS "1", `mapType` AS "2" FROM ::objectdifficulty WHERE `heroic25` > 0' ); $this->disables = DB::World()->selectCol( - 'SELECT IF(`sourceType`, ?d, ?d) AS ARRAY_KEY, `entry` AS ARRAY_KEY2, `entry` + 'SELECT IF(`sourceType`, %i, %i) AS ARRAY_KEY, `entry` AS ARRAY_KEY2, `entry` FROM disables WHERE (`sourceType` = 0 AND (`flags` & 0xF)) OR `sourceType` = 1', Type::QUEST, Type::SPELL ); CLI::write('[source] - resolving ref-loot tree', CLI::LOG_BLANK, true, true); - $this->refLoot = DB::World()->select( + $this->refLoot = DB::World()->selectAssoc( 'SELECT rlt.`Entry` AS ARRAY_KEY, IF(`Reference`, -`Reference`, `Item`) AS ARRAY_KEY2, it.`entry`, it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2` FROM reference_loot_template rlt LEFT JOIN item_template it ON rlt.`Reference` = 0 AND rlt.`Item` = it.`entry` @@ -98,7 +98,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript } } - DB::Aowow()->query('TRUNCATE ?_source'); + DB::Aowow()->qry('TRUNCATE ::source'); /***************************/ /* Item & inherited Spells */ @@ -190,23 +190,23 @@ CLISetup::registerSetup("sql", new class extends SetupScript // generally treat all items generated by spell as being available. The spells may be triggered in convoluted ways but usually _are_ in use. $itemSpellSource = DB::Aowow()->selectCol( 'SELECT x.`itemId` FROM ( - SELECT `effect1CreateItemId` AS "itemId", s.`id` FROM dbc_spell s WHERE `effect1CreateItemId` > 0 AND (`effect1Id` IN (?a) OR `effect1AuraId` IN (?a)) UNION ALL - SELECT `effect2CreateItemId` AS "itemId", s.`id` FROM dbc_spell s WHERE `effect2CreateItemId` > 0 AND (`effect2Id` IN (?a) OR `effect2AuraId` IN (?a)) UNION ALL - SELECT `effect3CreateItemId` AS "itemId", s.`id` FROM dbc_spell s WHERE `effect3CreateItemId` > 0 AND (`effect3Id` IN (?a) OR `effect3AuraId` IN (?a)) ) AS x - { WHERE x.`id` NOT IN (?a) }', + SELECT `effect1CreateItemId` AS "itemId", s.`id` FROM dbc_spell s WHERE `effect1CreateItemId` > 0 AND (`effect1Id` IN %in OR `effect1AuraId` IN %in) UNION ALL + SELECT `effect2CreateItemId` AS "itemId", s.`id` FROM dbc_spell s WHERE `effect2CreateItemId` > 0 AND (`effect2Id` IN %in OR `effect2AuraId` IN %in) UNION ALL + SELECT `effect3CreateItemId` AS "itemId", s.`id` FROM dbc_spell s WHERE `effect3CreateItemId` > 0 AND (`effect3Id` IN %in OR `effect3AuraId` IN %in) ) AS x + WHERE x.`id` NOT IN %in', SpellList::EFFECTS_ITEM_CREATE, SpellList::AURAS_ITEM_CREATE, SpellList::EFFECTS_ITEM_CREATE, SpellList::AURAS_ITEM_CREATE, SpellList::EFFECTS_ITEM_CREATE, SpellList::AURAS_ITEM_CREATE, - !empty($this->disables[Type::SPELL]) ? array_values($this->disables[Type::SPELL]) : DBSIMPLE_SKIP + $this->disables[Type::SPELL] ?? [0] ); // flagging aowow_items for source (note: this is not exact! creatures dropping items may not be spawned, etc.) - DB::Aowow()->query('UPDATE ?_items SET `cuFlags` = `cuFlags` & ?d', ~CUSTOM_UNAVAILABLE); - DB::Aowow()->query( - 'UPDATE ?_items i - LEFT JOIN ?_source s ON s.`typeId` = i.`id` AND s.`type` = ?d - SET i.`cuFlags` = i.`cuFlags` | ?d - WHERE (s.`typeId` IS NULL AND i.`id` NOT IN (?a)) OR i.`quality` = ?d', + DB::Aowow()->qry('UPDATE ::items SET `cuFlags` = `cuFlags` & %i', ~CUSTOM_UNAVAILABLE); + DB::Aowow()->qry( + 'UPDATE ::items i + LEFT JOIN ::source s ON s.`typeId` = i.`id` AND s.`type` = %i + SET i.`cuFlags` = i.`cuFlags` | %i + WHERE (s.`typeId` IS NULL AND i.`id` NOT IN %in) OR i.`quality` = %i', Type::ITEM, CUSTOM_UNAVAILABLE, $itemSpellSource, ITEM_QUALITY_ARTIFACT ); @@ -259,7 +259,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript } $rows = []; - DB::Aowow()->query('INSERT INTO ?_source VALUES '. substr($str, 0, -1)); + DB::Aowow()->qry('INSERT INTO ::source VALUES '. substr($str, 0, -1)); } private function taughtSpell(array $item) : int @@ -287,7 +287,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript 'SELECT `effect1CreateItemId` AS ARRAY_KEY, s.`id` FROM dbc_spell s JOIN dbc_skilllineability sla ON s.`id` = sla.`spellId` - WHERE `effect1CreateItemId` > 0 AND sla.`skillLineId` IN (?a) + WHERE `effect1CreateItemId` > 0 AND sla.`skillLineId` IN %in GROUP BY ARRAY_KEY', array_merge(SKILLS_TRADE_PRIMARY, [SKILL_FIRST_AID, SKILL_COOKING, SKILL_FISHING]) ); @@ -299,7 +299,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript $itemSpells = array_filter($itemSpells, fn($x) => empty($this->disables[Type::SPELL][$x])); - $spellLoot = DB::World()->selectCol('SELECT IF(`Reference` > 0, -`Reference`, `Item`) AS ARRAY_KEY, `entry` FROM spell_loot_template WHERE `entry` IN (?a)', $itemSpells); + $spellLoot = DB::World()->selectCol('SELECT IF(`Reference` > 0, -`Reference`, `Item`) AS ARRAY_KEY, `entry` FROM spell_loot_template WHERE `entry` IN %in', $itemSpells); if ($_ = array_filter($spellLoot, fn($x) => $x > 0, ARRAY_FILTER_USE_KEY)) $itemSpells = array_replace($itemSpells, $_); @@ -307,7 +307,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript if (isset($this->refLoot[-$r])) $itemSpells = array_replace(array_fill_keys(array_keys($this->refLoot[-$r]), $spellId)); - $spellItems = DB::World()->select('SELECT `entry` AS ARRAY_KEY, `class`, `subclass`, `spellid_1`, `spelltrigger_1`, `spellid_2`, `spelltrigger_2` FROM item_template WHERE `entry` IN (?a)', array_keys($itemSpells)); + $spellItems = DB::World()->selectAssoc('SELECT `entry` AS ARRAY_KEY, `class`, `subclass`, `spellid_1`, `spelltrigger_1`, `spellid_2`, `spelltrigger_2` FROM item_template WHERE `entry` IN %in', array_keys($itemSpells)); foreach ($spellItems as $iId => $si) { if ($_ = $this->taughtSpell($si)) @@ -324,7 +324,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[source] * #2 Drop [NPC]', CLI::LOG_BLANK, true, true); - $creatureLoot = DB::World()->select( + $creatureLoot = DB::World()->selectAssoc( 'SELECT IF(clt.`Reference` > 0, -clt.`Reference`, clt.`Item`) AS "refOrItem", ct.`entry`, it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`, COUNT(DISTINCT clt.`Reference`) AS "qty" FROM creature_loot_template clt JOIN creature_template ct ON clt.`entry` = ct.`lootid` @@ -333,9 +333,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript GROUP BY `refOrItem`, ct.`entry`' ); - $linkedNpcs = DB::Aowow()->selectCol('SELECT l1.`objectId` AS ARRAY_KEY, IFNULL(l2.`npcId`, l1.`npcId`) FROM ?_loot_link l1 LEFT JOIN ?_loot_link l2 ON l1.`objectId` = l2.`objectId` AND l2.`priority` = 1 GROUP BY l1.`objectid`'); - $npcSpawns = DB::Aowow()->select('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT s.`areaId`) > 1, 0, s.`areaId`) AS "areaId", z.`type` FROM ?_spawns s JOIN ?_zones z ON z.`id` = s.`areaId` WHERE s.`type` = ?d AND `typeId` IN (?a) GROUP BY `typeId`', Type::NPC, array_merge($linkedNpcs, array_filter(array_column($creatureLoot, 'entry')))); - $bosses = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, IF(`cuFlags` & ?d, 1, IF(`typeFlags` & 0x4 AND `rank` > 0, 1, 0)) FROM ?_creature WHERE `id` IN (?a)', NPC_CU_INSTANCE_BOSS, array_filter(array_column($creatureLoot, 'entry'))); + $linkedNpcs = DB::Aowow()->selectCol('SELECT l1.`objectId` AS ARRAY_KEY, IFNULL(l2.`npcId`, l1.`npcId`) FROM ::loot_link l1 LEFT JOIN ::loot_link l2 ON l1.`objectId` = l2.`objectId` AND l2.`priority` = 1 GROUP BY l1.`objectid`'); + $npcSpawns = DB::Aowow()->selectAssoc('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT s.`areaId`) > 1, 0, s.`areaId`) AS "areaId", z.`type` FROM ::spawns s JOIN ::zones z ON z.`id` = s.`areaId` WHERE s.`type` = %i AND `typeId` IN %in GROUP BY `typeId`', Type::NPC, array_merge($linkedNpcs, array_filter(array_column($creatureLoot, 'entry')))); + $bosses = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, IF(`cuFlags` & %i, 1, IF(`typeFlags` & 0x4 AND `rank` > 0, 1, 0)) FROM ::creature WHERE `id` IN %in', NPC_CU_INSTANCE_BOSS, array_filter(array_column($creatureLoot, 'entry'))); foreach ($creatureLoot as $l) { @@ -391,18 +391,18 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[source] * #2 Drop [Object]', CLI::LOG_BLANK, true, true); - $objectLoot = DB::World()->select( + $objectLoot = DB::World()->selectAssoc( 'SELECT IF(glt.`Reference` > 0, -glt.`Reference`, glt.`Item`) AS "refOrItem", gt.`entry`, it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`, COUNT(DISTINCT glt.`Reference`) AS "qty" FROM gameobject_loot_template glt JOIN gameobject_template gt ON glt.`entry` = gt.`data1` LEFT JOIN item_template it ON it.`entry` = glt.`Item` AND glt.`Reference` <= 0 - WHERE `type` = ?d AND gt.`data1` > 0 AND gt.`data0` NOT IN (?a) + WHERE `type` = %i AND gt.`data1` > 0 AND gt.`data0` NOT IN %in GROUP BY `refOrItem`, gt.`entry`', OBJECT_CHEST, - DB::Aowow()->selectCol('SELECT `id` FROM dbc_lock WHERE `properties1` IN (?a)', [LOCK_PROPERTY_HERBALISM, LOCK_PROPERTY_MINING]) + DB::Aowow()->selectCol('SELECT `id` FROM dbc_lock WHERE `properties1` IN %in', [LOCK_PROPERTY_HERBALISM, LOCK_PROPERTY_MINING]) ); - $goSpawns = DB::Aowow()->select('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT s.`areaId`) > 1, 0, s.`areaId`) AS "areaId", z.`type` FROM ?_spawns s JOIN ?_zones z ON z.`id` = s.`areaId` WHERE s.`type` = ?d AND `typeId`IN (?a) GROUP BY `typeId`', Type::OBJECT, array_filter(array_column($objectLoot, 'entry'))); + $goSpawns = DB::Aowow()->selectAssoc('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT s.`areaId`) > 1, 0, s.`areaId`) AS "areaId", z.`type` FROM ::spawns s JOIN ::zones z ON z.`id` = s.`areaId` WHERE s.`type` = %i AND `typeId`IN %in GROUP BY `typeId`', Type::OBJECT, array_filter(array_column($objectLoot, 'entry'))); foreach ($objectLoot as $l) { @@ -469,24 +469,24 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[source] * #2 Drop [Item]', CLI::LOG_BLANK, true, true); - $itemLoot = DB::World()->select( + $itemLoot = DB::World()->selectAssoc( 'SELECT IF(ilt.`Reference` > 0, -ilt.`Reference`, ilt.`Item`) AS ARRAY_KEY, itA.`entry`, itB.`class`, itB.`subclass`, itB.`spellid_1`, itB.`spelltrigger_1`, itB.`spellid_2`, itB.`spelltrigger_2`, COUNT(DISTINCT ilt.`Reference`) AS "qty" FROM item_loot_template ilt JOIN item_template itA ON ilt.`entry` = itA.`entry` LEFT JOIN item_template itB ON itB.`entry` = ilt.`Item` AND ilt.`Reference` <= 0 - WHERE itA.`flags` & ?d + WHERE itA.`flags` & %i GROUP BY ARRAY_KEY', ITEM_FLAG_OPENABLE ); // Clams are not item containers but have SpellLoot - $lootSpells = DB::Aowow()->selectCol('SELECT s.`id` FROM ?_spell s JOIN ?_items i ON i.`spellId1` = s.`id` AND i.`spellTrigger1` = ?d WHERE s.`effect1Id` = ?d', SPELL_TRIGGER_USE, SPELL_EFFECT_CREATE_RANDOM_ITEM); - $spellLoot = DB::World()->select( + $lootSpells = DB::Aowow()->selectCol('SELECT s.`id` FROM ::spell s JOIN ::items i ON i.`spellId1` = s.`id` AND i.`spellTrigger1` = %i WHERE s.`effect1Id` = %i', SPELL_TRIGGER_USE, SPELL_EFFECT_CREATE_RANDOM_ITEM); + $spellLoot = DB::World()->selectAssoc( 'SELECT IF(slt.`Reference` > 0, -slt.`Reference`, slt.`Item`) AS ARRAY_KEY, itA.`entry`, itB.`class`, itB.`subclass`, itB.`spellid_1`, itB.`spelltrigger_1`, itB.`spellid_2`, itB.`spelltrigger_2`, COUNT(DISTINCT slt.`Reference`) AS "qty" FROM spell_loot_template slt JOIN item_template itA ON slt.`entry` = itA.`spellid_1` LEFT JOIN item_template itB ON itB.`entry` = slt.`Item` AND slt.`Reference` <= 0 - WHERE itA.`spellid_1` IN (?a) AND itA.`spelltrigger_1` = ?d + WHERE itA.`spellid_1` IN %in AND itA.`spelltrigger_1` = %i GROUP BY ARRAY_KEY', $lootSpells, SPELL_TRIGGER_USE ); @@ -518,9 +518,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript } if ($itemOT) - DB::Aowow()->query('UPDATE ?_items SET `cuFLags` = `cuFlags` | ?d WHERE `id` IN (?a)', ITEM_CU_OT_ITEMLOOT, $itemOT); + DB::Aowow()->qry('UPDATE ::items SET `cuFLags` = `cuFlags` | %i WHERE `id` IN %in', ITEM_CU_OT_ITEMLOOT, $itemOT); if ($objectOT) - DB::Aowow()->query('UPDATE ?_items SET `cuFLags` = `cuFlags` | ?d WHERE `id` IN (?a)', ITEM_CU_OT_OBJECTLOOT, $objectOT); + DB::Aowow()->qry('UPDATE ::items SET `cuFLags` = `cuFlags` | %i WHERE `id` IN %in', ITEM_CU_OT_OBJECTLOOT, $objectOT); } private function itemPvP() : void @@ -530,19 +530,19 @@ CLISetup::registerSetup("sql", new class extends SetupScript $subSrcByXCost = array( SRC_SUB_PVP_BG => DB::Aowow()->selectCol('SELECT `id` FROM dbc_itemextendedcost WHERE `reqArenaPoints` = 0 AND `reqHonorPoints` > 0'), SRC_SUB_PVP_ARENA => DB::Aowow()->selectCol('SELECT `id` FROM dbc_itemextendedcost WHERE `reqArenaPoints` > 0'), - SRC_SUB_PVP_WORLD => DB::Aowow()->selectCol('SELECT `id` FROM dbc_itemextendedcost WHERE `reqItemId1` IN (?a) OR `reqItemId2` IN (?a) OR `reqItemId3` IN (?a) OR `reqItemId4` IN (?a) OR `reqItemId5` IN (?a)', self::PVP_MONEY, self::PVP_MONEY, self::PVP_MONEY, self::PVP_MONEY, self::PVP_MONEY) + SRC_SUB_PVP_WORLD => DB::Aowow()->selectCol('SELECT `id` FROM dbc_itemextendedcost WHERE `reqItemId1` IN %in OR `reqItemId2` IN %in OR `reqItemId3` IN %in OR `reqItemId4` IN %in OR `reqItemId5` IN %in', self::PVP_MONEY, self::PVP_MONEY, self::PVP_MONEY, self::PVP_MONEY, self::PVP_MONEY) ); $vendorQuery = 'SELECT n.`item`, SUM(n.`qty`) AS "qty", it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2` - FROM (SELECT `item`, COUNT(1) AS "qty" FROM npc_vendor WHERE `ExtendedCost` IN (?a) AND `item` > 0 GROUP BY `item` UNION - SELECT nv2.`item`, COUNT(1) AS "qty" FROM npc_vendor nv1 JOIN npc_vendor nv2 ON nv2.`entry` = -nv1.`item` AND nv1.`item` < 0 WHERE nv1.`ExtendedCost` IN (?a) AND `nv1`.`item` < 0 GROUP BY `item` UNION - SELECT `item`, COUNT(1) AS "qty" FROM game_event_npc_vendor genv JOIN creature c ON c.`guid` = genv.`guid` WHERE `ExtendedCost` IN (?a) GROUP BY `item`) n + FROM (SELECT `item`, COUNT(1) AS "qty" FROM npc_vendor WHERE `ExtendedCost` IN %in AND `item` > 0 GROUP BY `item` UNION + SELECT nv2.`item`, COUNT(1) AS "qty" FROM npc_vendor nv1 JOIN npc_vendor nv2 ON nv2.`entry` = -nv1.`item` AND nv1.`item` < 0 WHERE nv1.`ExtendedCost` IN %in AND `nv1`.`item` < 0 GROUP BY `item` UNION + SELECT `item`, COUNT(1) AS "qty" FROM game_event_npc_vendor genv JOIN creature c ON c.`guid` = genv.`guid` WHERE `ExtendedCost` IN %in GROUP BY `item`) n JOIN item_template it ON it.`entry` = n.`item` GROUP BY `item`'; foreach ($subSrcByXCost as $subSrc => $xCost) { - foreach (DB::World()->select($vendorQuery, $xCost, $xCost, $xCost) as $v) + foreach (DB::World()->selectAssoc($vendorQuery, $xCost, $xCost, $xCost) as $v) { if ($_ = $this->taughtSpell($v)) $this->pushBuffer(Type::SPELL, $_, SRC_PVP, $subSrc); @@ -556,21 +556,21 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #4 Quest', CLI::LOG_BLANK, true, true); - $quests = DB::World()->select( + $quests = DB::World()->selectAssoc( 'SELECT n.`item` AS ARRAY_KEY, n.`ID` AS "quest", SUM(n.`qty`) AS "qty", BIT_OR(n.`side`) AS "side", IF(COUNT(DISTINCT `zone`) > 1, 0, `zone`) AS "zone", it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2` - FROM (SELECT `RewardChoiceItemID1` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID1` > 0 UNION ALL - SELECT `RewardChoiceItemID2` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID2` > 0 UNION ALL - SELECT `RewardChoiceItemID3` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID3` > 0 UNION ALL - SELECT `RewardChoiceItemID4` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID4` > 0 UNION ALL - SELECT `RewardChoiceItemID5` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID5` > 0 UNION ALL - SELECT `RewardChoiceItemID6` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID6` > 0 UNION ALL - SELECT `RewardItem1` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardItem1` > 0 UNION ALL - SELECT `RewardItem2` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardItem2` > 0 UNION ALL - SELECT `RewardItem3` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardItem3` > 0 UNION ALL - SELECT `RewardItem4` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardItem4` > 0 UNION ALL - SELECT `StartItem` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `StartItem` > 0) n + FROM (SELECT `RewardChoiceItemID1` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID1` > 0 UNION ALL + SELECT `RewardChoiceItemID2` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID2` > 0 UNION ALL + SELECT `RewardChoiceItemID3` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID3` > 0 UNION ALL + SELECT `RewardChoiceItemID4` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID4` > 0 UNION ALL + SELECT `RewardChoiceItemID5` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID5` > 0 UNION ALL + SELECT `RewardChoiceItemID6` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardChoiceItemID6` > 0 UNION ALL + SELECT `RewardItem1` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardItem1` > 0 UNION ALL + SELECT `RewardItem2` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardItem2` > 0 UNION ALL + SELECT `RewardItem3` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardItem3` > 0 UNION ALL + SELECT `RewardItem4` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardItem4` > 0 UNION ALL + SELECT `StartItem` AS "item", `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `StartItem` > 0) n JOIN item_template it ON it.`entry` = n.`item` - { WHERE n.`ID` NOT IN (?a) } + WHERE n.`ID` NOT IN %in GROUP BY `item`', ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH, ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH, @@ -583,9 +583,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH, ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH, ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH, - !empty($this->disables[Type::QUEST]) ? array_values($this->disables[Type::QUEST]) : DBSIMPLE_SKIP + $this->disables[Type::QUEST] ?? [0] ); - $areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ?_zones WHERE `id` IN (?a) AND `parentArea` > 0', array_filter(array_column($quests, 'zone'))); + $areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ::zones WHERE `id` IN %in AND `parentArea` > 0', array_filter(array_column($quests, 'zone'))); foreach ($quests as $iId => $q) { @@ -598,8 +598,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript $this->pushBuffer(Type::ITEM, $iId, SRC_QUEST, $q['side'], $q['qty'] > 1 ? 0 : Type::QUEST, $q['quest'], $areaParent[$q['zone']] ?? Game::$questSortFix[$q['zone']] ?? $q['zone']); } - $mailLoot = DB::World()->select( - 'SELECT IF(mlt.`Reference` > 0, -mlt.`Reference`, mlt.`Item`) AS ARRAY_KEY, qt.`Id` AS "entry", it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`, COUNT(DISTINCT mlt.`Reference`) AS "qty", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone", BIT_OR(IF(qt.`AllowableRaces` & ?d AND NOT (qt.`AllowableRaces` & ?d), ?d, IF(qt.`AllowableRaces` & ?d AND NOT (qt.`AllowableRaces` & ?d), ?d, ?d))) AS "side" + $mailLoot = DB::World()->selectAssoc( + 'SELECT IF(mlt.`Reference` > 0, -mlt.`Reference`, mlt.`Item`) AS ARRAY_KEY, qt.`Id` AS "entry", it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`, COUNT(DISTINCT mlt.`Reference`) AS "qty", IF(COUNT(DISTINCT `QuestSortID`) > 1, 0, GREATEST(`QuestSortID`, 0)) AS "zone", BIT_OR(IF(qt.`AllowableRaces` & %i AND NOT (qt.`AllowableRaces` & %i), %i, IF(qt.`AllowableRaces` & %i AND NOT (qt.`AllowableRaces` & %i), %i, %i))) AS "side" FROM mail_loot_template mlt JOIN quest_template_addon qta ON qta.`RewardMailTemplateId` = mlt.`entry` JOIN quest_template qt ON qt.`ID` = qta.`ID` @@ -609,7 +609,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH ); - $areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ?_zones WHERE `id` IN (?a) AND `parentArea` > 0', array_filter(array_column($mailLoot, 'zone'))); + $areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ::zones WHERE `id` IN %in AND `parentArea` > 0', array_filter(array_column($mailLoot, 'zone'))); foreach ($mailLoot as $roi => $l) { @@ -642,18 +642,18 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #5 Vendor', CLI::LOG_BLANK, true, true); - $xCostIds = DB::Aowow()->selectCol('SELECT `id` FROM dbc_itemextendedcost WHERE `reqHonorPoints` <> 0 OR `reqArenaPoints` <> 0 OR `reqItemId1` IN (?a) OR `reqItemId2` IN (?a) OR `reqItemId3` IN (?a) OR `reqItemId4` IN (?a) OR `reqItemId5` IN (?a)', self::PVP_MONEY, self::PVP_MONEY, self::PVP_MONEY, self::PVP_MONEY, self::PVP_MONEY); - $vendors = DB::World()->select( + $xCostIds = DB::Aowow()->selectCol('SELECT `id` FROM dbc_itemextendedcost WHERE `reqHonorPoints` <> 0 OR `reqArenaPoints` <> 0 OR `reqItemId1` IN %in OR `reqItemId2` IN %in OR `reqItemId3` IN %in OR `reqItemId4` IN %in OR `reqItemId5` IN %in', self::PVP_MONEY, self::PVP_MONEY, self::PVP_MONEY, self::PVP_MONEY, self::PVP_MONEY); + $vendors = DB::World()->selectAssoc( 'SELECT n.`item`, n.`npc`, SUM(n.`qty`) AS "qty", it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2` - FROM (SELECT `item`, `entry` AS "npc", COUNT(1) AS "qty" FROM npc_vendor WHERE `ExtendedCost` NOT IN (?a) AND `item` > 0 GROUP BY `item`, `npc` UNION - SELECT nv2.`item`, nv1.`entry` AS "npc", COUNT(1) AS "qty" FROM npc_vendor nv1 JOIN npc_vendor nv2 ON nv2.`entry` = -nv1.`item` AND nv1.`item` < 0 WHERE nv1.`ExtendedCost` NOT IN (?a) AND `nv1`.`item` < 0 GROUP BY `item`, `npc` UNION - SELECT `item`, c.`id` AS "npc", COUNT(1) AS "qty" FROM game_event_npc_vendor genv JOIN creature c ON c.`guid` = genv.`guid` WHERE `ExtendedCost` NOT IN (?a) GROUP BY `item`, `npc`) n + FROM (SELECT `item`, `entry` AS "npc", COUNT(1) AS "qty" FROM npc_vendor WHERE `ExtendedCost` NOT IN %in AND `item` > 0 GROUP BY `item`, `npc` UNION + SELECT nv2.`item`, nv1.`entry` AS "npc", COUNT(1) AS "qty" FROM npc_vendor nv1 JOIN npc_vendor nv2 ON nv2.`entry` = -nv1.`item` AND nv1.`item` < 0 WHERE nv1.`ExtendedCost` NOT IN %in AND `nv1`.`item` < 0 GROUP BY `item`, `npc` UNION + SELECT `item`, c.`id` AS "npc", COUNT(1) AS "qty" FROM game_event_npc_vendor genv JOIN creature c ON c.`guid` = genv.`guid` WHERE `ExtendedCost` NOT IN %in GROUP BY `item`, `npc`) n JOIN item_template it ON it.`entry` = n.`item` GROUP BY `item`, `npc`', $xCostIds, $xCostIds, $xCostIds ); - $spawns = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId`IN (?a) GROUP BY `typeId`', Type::NPC, array_column($vendors, 'npc')); + $spawns = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ::spawns WHERE `type` = %i AND `typeId`IN %in GROUP BY `typeId`', Type::NPC, array_column($vendors, 'npc')); foreach ($vendors as $v) { @@ -673,7 +673,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript $this->pushBuffer(Type::ITEM, $item, SRC_STARTER); for ($i = 1; $i < 21; $i++) - if ($cso = DB::Aowow()->selectCol('SELECT ?# FROM dbc_charstartoutfit WHERE ?# > 0', 'item'.$i, 'item'.$i)) + if ($cso = DB::Aowow()->selectCol('SELECT %n FROM dbc_charstartoutfit WHERE %n > 0', 'item'.$i, 'item'.$i)) foreach ($cso as $item) $this->pushBuffer(Type::ITEM, $item, SRC_STARTER); } @@ -682,8 +682,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #12 Achievement', CLI::LOG_BLANK, true, true); - $xItems = DB::Aowow()->select('SELECT `id` AS "entry", `itemExtra` AS ARRAY_KEY, COUNT(1) AS "qty" FROM ?_achievement WHERE `itemExtra` > 0 GROUP BY `itemExtra`'); - $rewItems = DB::World()->select( + $xItems = DB::Aowow()->selectAssoc('SELECT `id` AS "entry", `itemExtra` AS ARRAY_KEY, COUNT(1) AS "qty" FROM ::achievement WHERE `itemExtra` > 0 GROUP BY `itemExtra`'); + $rewItems = DB::World()->selectAssoc( 'SELECT src.`item` AS ARRAY_KEY, src.`entry`, it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`, COUNT(1) AS "qty" FROM (SELECT IFNULL(IF(mlt.`Reference` > 0, -mlt.`Reference`, mlt.`Item`), ar.`ItemID`) AS "item", ar.`ID` AS "entry" FROM achievement_reward ar @@ -697,7 +697,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[source] itemAchievement() - Reward items are unexpectedly empty.', CLI::LOG_WARN); else { - $extraItems = DB::World()->select('SELECT `entry` AS ARRAY_KEY, `class`, `subclass`, `spellid_1`, `spelltrigger_1`, `spellid_2`, `spelltrigger_2` FROM item_template WHERE `entry` IN (?a)', array_keys($xItems)); + $extraItems = DB::World()->selectAssoc('SELECT `entry` AS ARRAY_KEY, `class`, `subclass`, `spellid_1`, `spelltrigger_1`, `spellid_2`, `spelltrigger_2` FROM item_template WHERE `entry` IN %in', array_keys($xItems)); foreach ($extraItems as $iId => $l) { if ($_ = $this->taughtSpell($l)) @@ -720,7 +720,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #15 Disenchanted', CLI::LOG_BLANK, true, true); - $deLoot = DB::World()->select( + $deLoot = DB::World()->selectAssoc( 'SELECT IF(dlt.`Reference` > 0, -dlt.`Reference`, dlt.`Item`) AS "refOrItem", itA.`entry`, itB.`class`, itB.`subclass`, itB.`spellid_1`, itB.`spelltrigger_1`, itB.`spellid_2`, itB.`spelltrigger_2`, COUNT(DISTINCT dlt.`Reference`) AS "qty" FROM disenchant_loot_template dlt JOIN item_template itA ON dlt.`entry` = itA.`DisenchantId` @@ -757,10 +757,10 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #16 Fished', CLI::LOG_BLANK, true, true); - $fishLoot = DB::World()->select( + $fishLoot = DB::World()->selectAssoc( 'SELECT src.`itemOrRef` AS "refOrItem", src.`entry`, it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`, COUNT(DISTINCT src.`itemOrRef`) AS "qty", IF(COUNT(DISTINCT `zone`) > 2, 0, MAX(`zone`)) AS "zone" FROM (SELECT 0 AS "entry", IF(flt.`Reference` > 0, -flt.`Reference`, flt.`Item`) AS "itemOrRef", `entry` AS "zone" FROM fishing_loot_template flt UNION - SELECT gt.`entry`, IF(glt.`Reference` > 0, -glt.`Reference`, glt.`Item`) AS "itemOrRef", 0 AS "zone" FROM gameobject_template gt JOIN gameobject_loot_template glt ON glt.`entry` = gt.`data1` WHERE `type` = ?d AND gt.`data1` > 0) src + SELECT gt.`entry`, IF(glt.`Reference` > 0, -glt.`Reference`, glt.`Item`) AS "itemOrRef", 0 AS "zone" FROM gameobject_template gt JOIN gameobject_loot_template glt ON glt.`entry` = gt.`data1` WHERE `type` = %i AND gt.`data1` > 0) src LEFT JOIN item_template it ON src.`itemOrRef` > 0 AND src.`itemOrRef` = it.`entry` GROUP BY `refOrItem`, src.`entry`', OBJECT_FISHINGHOLE @@ -772,8 +772,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript return; } - $goSpawns = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId`IN (?a) GROUP BY `typeId`', Type::OBJECT, array_filter(array_column($fishLoot, 'entry'))); - $areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ?_zones WHERE `id` IN (?a) AND `parentArea` > 0', array_filter(array_column($fishLoot, 'zone'))); + $goSpawns = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ::spawns WHERE `type` = %i AND `typeId`IN %in GROUP BY `typeId`', Type::OBJECT, array_filter(array_column($fishLoot, 'entry'))); + $areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ::zones WHERE `id` IN %in AND `parentArea` > 0', array_filter(array_column($fishLoot, 'zone'))); foreach ($fishLoot as $l) { @@ -807,14 +807,14 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #17 Gathered', CLI::LOG_BLANK, true, true); - $herbLoot = DB::World()->select( + $herbLoot = DB::World()->selectAssoc( 'SELECT src.`itemOrRef` AS "refOrItem", src.`entry`, it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`, COUNT(DISTINCT src.`itemOrRef`) AS "qty", src.`srcType` - FROM (SELECT ct.`entry`, IF(slt.`Reference` > 0, -slt.`Reference`, slt.`Item`) `itemOrRef`, ?d AS "srcType" FROM creature_template ct JOIN skinning_loot_template slt ON slt.`entry` = ct.`skinloot` WHERE (`type_flags` & ?d) AND ct.`skinloot` > 0 UNION - SELECT gt.`entry`, IF(glt.`Reference` > 0, -glt.`Reference`, glt.`Item`) `itemOrRef`, ?d AS "srcType" FROM gameobject_template gt JOIN gameobject_loot_template glt ON glt.`entry` = gt.`data1` WHERE gt.`type` = ?d AND gt.`data1` > 0 AND gt.`data0` IN (?a)) src + FROM (SELECT ct.`entry`, IF(slt.`Reference` > 0, -slt.`Reference`, slt.`Item`) `itemOrRef`, %i AS "srcType" FROM creature_template ct JOIN skinning_loot_template slt ON slt.`entry` = ct.`skinloot` WHERE (`type_flags` & %i) AND ct.`skinloot` > 0 UNION + SELECT gt.`entry`, IF(glt.`Reference` > 0, -glt.`Reference`, glt.`Item`) `itemOrRef`, %i AS "srcType" FROM gameobject_template gt JOIN gameobject_loot_template glt ON glt.`entry` = gt.`data1` WHERE gt.`type` = %i AND gt.`data1` > 0 AND gt.`data0` IN %in) src LEFT JOIN item_template it ON src.itemOrRef > 0 AND src.`itemOrRef` = it.`entry` GROUP BY `refOrItem`, src.`entry`', Type::NPC, NPC_TYPEFLAG_SKIN_WITH_HERBALISM, - Type::OBJECT, OBJECT_CHEST, DB::Aowow()->selectCol('SELECT `id` FROM dbc_lock WHERE `properties1` = ?d', LOCK_PROPERTY_HERBALISM) + Type::OBJECT, OBJECT_CHEST, DB::Aowow()->selectCol('SELECT `id` FROM dbc_lock WHERE `properties1` = %i', LOCK_PROPERTY_HERBALISM) ); if (!$herbLoot) @@ -823,8 +823,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript return; } - $spawns[Type::OBJECT] = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId` IN (?a) GROUP BY `typeId`', Type::OBJECT, array_column(array_filter($herbLoot, fn($x) => $x['srcType'] == Type::OBJECT), 'entry')); - $spawns[Type::NPC] = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId` IN (?a) GROUP BY `typeId`', Type::NPC, array_column(array_filter($herbLoot, fn($x) => $x['srcType'] == Type::NPC), 'entry')); + $spawns[Type::OBJECT] = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ::spawns WHERE `type` = %i AND `typeId` IN %in GROUP BY `typeId`', Type::OBJECT, array_column(array_filter($herbLoot, fn($x) => $x['srcType'] == Type::OBJECT), 'entry')); + $spawns[Type::NPC] = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ::spawns WHERE `type` = %i AND `typeId` IN %in GROUP BY `typeId`', Type::NPC, array_column(array_filter($herbLoot, fn($x) => $x['srcType'] == Type::NPC), 'entry')); foreach ($herbLoot as $l) { @@ -860,7 +860,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #18 Milled', CLI::LOG_BLANK, true, true); - $millLoot = DB::World()->select( + $millLoot = DB::World()->selectAssoc( 'SELECT IF(mlt.`Reference` > 0, -mlt.`Reference`, mlt.`Item`) AS "refOrItem", itA.`entry`, itB.`class`, itB.`subclass`, itB.`spellid_1`, itB.`spelltrigger_1`, itB.`spellid_2`, itB.`spelltrigger_2`, COUNT(DISTINCT mlt.`Reference`) AS "qty" FROM milling_loot_template mlt JOIN item_template itA ON mlt.`entry` = itA.`entry` @@ -896,14 +896,14 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #19 Mined', CLI::LOG_BLANK, true, true); - $mineLoot = DB::World()->select( + $mineLoot = DB::World()->selectAssoc( 'SELECT src.`itemOrRef` AS "refOrItem", src.`entry`, it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`, COUNT(DISTINCT src.`itemOrRef`) AS "qty", src.`srcType` - FROM (SELECT ct.`entry`, IF(slt.`Reference` > 0, -slt.`Reference`, slt.`Item`) `itemOrRef`, ?d AS "srcType" FROM creature_template ct JOIN skinning_loot_template slt ON slt.`entry` = ct.`skinloot` WHERE (`type_flags` & ?d) AND ct.`skinloot` > 0 UNION - SELECT gt.`entry`, IF(glt.`Reference` > 0, -glt.`Reference`, glt.`Item`) `itemOrRef`, ?d AS "srcType" FROM gameobject_template gt JOIN gameobject_loot_template glt ON glt.`entry` = gt.`data1` WHERE gt.`type` = ?d AND gt.`data1` > 0 AND gt.`data0` IN (?a)) src + FROM (SELECT ct.`entry`, IF(slt.`Reference` > 0, -slt.`Reference`, slt.`Item`) `itemOrRef`, %i AS "srcType" FROM creature_template ct JOIN skinning_loot_template slt ON slt.`entry` = ct.`skinloot` WHERE (`type_flags` & %i) AND ct.`skinloot` > 0 UNION + SELECT gt.`entry`, IF(glt.`Reference` > 0, -glt.`Reference`, glt.`Item`) `itemOrRef`, %i AS "srcType" FROM gameobject_template gt JOIN gameobject_loot_template glt ON glt.`entry` = gt.`data1` WHERE gt.`type` = %i AND gt.`data1` > 0 AND gt.`data0` IN %in) src LEFT JOIN item_template it ON src.itemOrRef > 0 AND src.`itemOrRef` = it.`entry` GROUP BY `refOrItem`, src.`entry`', Type::NPC, NPC_TYPEFLAG_SKIN_WITH_MINING, - Type::OBJECT, OBJECT_CHEST, DB::Aowow()->selectCol('SELECT `id` FROM dbc_lock WHERE `properties1` = ?d', LOCK_PROPERTY_MINING) + Type::OBJECT, OBJECT_CHEST, DB::Aowow()->selectCol('SELECT `id` FROM dbc_lock WHERE `properties1` = %i', LOCK_PROPERTY_MINING) ); if (!$mineLoot) @@ -912,8 +912,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript return; } - $spawns[Type::OBJECT] = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId`IN (?a) GROUP BY `typeId`', Type::OBJECT, array_column(array_filter($mineLoot, fn($x) => $x['srcType'] == Type::OBJECT), 'entry')); - $spawns[Type::NPC] = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId`IN (?a) GROUP BY `typeId`', Type::NPC, array_column(array_filter($mineLoot, fn($x) => $x['srcType'] == Type::NPC), 'entry')); + $spawns[Type::OBJECT] = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ::spawns WHERE `type` = %i AND `typeId`IN %in GROUP BY `typeId`', Type::OBJECT, array_column(array_filter($mineLoot, fn($x) => $x['srcType'] == Type::OBJECT), 'entry')); + $spawns[Type::NPC] = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ::spawns WHERE `type` = %i AND `typeId`IN %in GROUP BY `typeId`', Type::NPC, array_column(array_filter($mineLoot, fn($x) => $x['srcType'] == Type::NPC), 'entry')); foreach ($mineLoot as $l) { @@ -949,7 +949,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #20 Prospected', CLI::LOG_BLANK, true, true); - $prospectLoot = DB::World()->select( + $prospectLoot = DB::World()->selectAssoc( 'SELECT IF(plt.`Reference` > 0, -plt.`Reference`, plt.`Item`) AS "refOrItem", itA.`entry`, itB.`class`, itB.`subclass`, itB.`spellid_1`, itB.`spelltrigger_1`, itB.`spellid_2`, itB.`spelltrigger_2`, COUNT(DISTINCT plt.`Reference`) AS "qty" FROM prospecting_loot_template plt JOIN item_template itA ON plt.`entry` = itA.`entry` @@ -985,7 +985,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #21 Pickpocket', CLI::LOG_BLANK, true, true); - $theftLoot = DB::World()->select( + $theftLoot = DB::World()->selectAssoc( 'SELECT src.`itemOrRef` AS "refOrItem", src.`entry`, it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`, COUNT(DISTINCT src.`itemOrRef`) AS "qty" FROM (SELECT ct.`entry`, IF(plt.`Reference` > 0, -plt.`Reference`, plt.`Item`) `itemOrRef` FROM creature_template ct JOIN pickpocketing_loot_template plt ON plt.`entry` = ct.`pickpocketloot` WHERE ct.`pickpocketloot` > 0) src LEFT JOIN item_template it ON src.`itemOrRef` > 0 AND src.`itemOrRef` = it.`entry` @@ -998,7 +998,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript return; } - $spawns = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId`IN (?a) GROUP BY `typeId`', Type::NPC, array_filter(array_column($theftLoot, 'entry'))); + $spawns = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ::spawns WHERE `type` = %i AND `typeId`IN %in GROUP BY `typeId`', Type::NPC, array_filter(array_column($theftLoot, 'entry'))); foreach ($theftLoot as $l) { @@ -1034,9 +1034,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #22 Salvaged', CLI::LOG_BLANK, true, true); - $salvageLoot = DB::World()->select( + $salvageLoot = DB::World()->selectAssoc( 'SELECT src.`itemOrRef` AS "refOrItem", src.`entry`, it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`, COUNT(DISTINCT src.`itemOrRef`) AS "qty" - FROM (SELECT ct.`entry`, IF(slt.`Reference` > 0, -slt.`Reference`, slt.`Item`) `itemOrRef` FROM creature_template ct JOIN skinning_loot_template slt ON slt.`entry` = ct.`skinloot` WHERE (`type_flags` & ?d) AND ct.`skinloot` > 0) src + FROM (SELECT ct.`entry`, IF(slt.`Reference` > 0, -slt.`Reference`, slt.`Item`) `itemOrRef` FROM creature_template ct JOIN skinning_loot_template slt ON slt.`entry` = ct.`skinloot` WHERE (`type_flags` & %i) AND ct.`skinloot` > 0) src LEFT JOIN item_template it ON src.`itemOrRef` > 0 AND src.`itemOrRef` = it.`entry` GROUP BY `refOrItem`, src.`entry`', NPC_TYPEFLAG_SKIN_WITH_ENGINEERING @@ -1048,7 +1048,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript return; } - $spawns = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId`IN (?a) GROUP BY `typeId`', Type::NPC, array_filter(array_column($salvageLoot, 'entry'))); + $spawns = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ::spawns WHERE `type` = %i AND `typeId`IN %in GROUP BY `typeId`', Type::NPC, array_filter(array_column($salvageLoot, 'entry'))); foreach ($salvageLoot as $l) { @@ -1084,9 +1084,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #23 Skinned', CLI::LOG_BLANK, true, true); - $skinLoot = DB::World()->select( + $skinLoot = DB::World()->selectAssoc( 'SELECT src.`itemOrRef` AS "refOrItem", src.`entry`, it.`class`, it.`subclass`, it.`spellid_1`, it.`spelltrigger_1`, it.`spellid_2`, it.`spelltrigger_2`, COUNT(DISTINCT src.`itemOrRef`) AS "qty" - FROM (SELECT ct.`entry`, IF(slt.`Reference` > 0, -slt.`Reference`, slt.`Item`) `itemOrRef` FROM creature_template ct JOIN skinning_loot_template slt ON slt.`entry` = ct.`skinloot` WHERE (`type_flags` & ?d) = 0 AND ct.`skinloot` > 0 AND ct.`type` <> 13) src + FROM (SELECT ct.`entry`, IF(slt.`Reference` > 0, -slt.`Reference`, slt.`Item`) `itemOrRef` FROM creature_template ct JOIN skinning_loot_template slt ON slt.`entry` = ct.`skinloot` WHERE (`type_flags` & %i) = 0 AND ct.`skinloot` > 0 AND ct.`type` <> 13) src LEFT JOIN item_template it ON src.`itemOrRef` > 0 AND src.`itemOrRef` = it.`entry` GROUP BY `refOrItem`, src.`entry`', NPC_TYPEFLAG_SPECIALLOOT @@ -1098,7 +1098,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript return; } - $spawns = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ?_spawns WHERE `type` = ?d AND `typeId`IN (?a) GROUP BY `typeId`', Type::NPC, array_filter(array_column($skinLoot, 'entry'))); + $spawns = DB::Aowow()->selectCol('SELECT `typeId` AS ARRAY_KEY, IF(COUNT(DISTINCT `areaId`) > 1, 0, `areaId`) FROM ::spawns WHERE `type` = %i AND `typeId`IN %in GROUP BY `typeId`', Type::NPC, array_filter(array_column($skinLoot, 'entry'))); foreach ($skinLoot as $l) { @@ -1134,15 +1134,15 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #4 Quest', CLI::LOG_BLANK, true, true); - $quests = DB::World()->select( + $quests = DB::World()->selectAssoc( 'SELECT `spell` AS ARRAY_KEY, `ID` AS "id", SUM(`qty`) AS "qty", BIT_OR(`side`) AS "side", IF(COUNT(DISTINCT `zone`) > 1, 0, `zone`) AS "zone" - FROM (SELECT IF(`RewardSpell` = 0, `RewardDisplaySpell`, `RewardSpell`) AS "spell", `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE IF(`RewardSpell` = 0, `RewardDisplaySpell`, `RewardSpell`) > 0 UNION ALL - SELECT qta.`SourceSpellId` AS "spell", qt.`ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template qt JOIN quest_template_addon qta ON qta.ID = qt.ID WHERE qta.`SourceSpellId` > 0 ) t - { WHERE t.`ID` NOT IN (?a) } + FROM (SELECT IF(`RewardSpell` = 0, `RewardDisplaySpell`, `RewardSpell`) AS "spell", `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE IF(`RewardSpell` = 0, `RewardDisplaySpell`, `RewardSpell`) > 0 UNION ALL + SELECT qta.`SourceSpellId` AS "spell", qt.`ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template qt JOIN quest_template_addon qta ON qta.ID = qt.ID WHERE qta.`SourceSpellId` > 0 ) t + WHERE t.`ID` NOT IN %in GROUP BY `spell`', ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH, ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH, - !empty($this->disables[Type::QUEST]) ? array_values($this->disables[Type::QUEST]) : DBSIMPLE_SKIP + $this->disables[Type::QUEST] ?? [0] ); if (!$quests) @@ -1151,8 +1151,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript return; } - $areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ?_zones WHERE `id` IN (?a) AND `parentArea` > 0', array_filter(array_column($quests, 'zone'))); - $qSpells = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `effect1Id`, `effect2Id`, `effect3Id`, `effect1TriggerSpell`, `effect2TriggerSpell`, `effect3TriggerSpell` FROM dbc_spell WHERE `id` IN (?a) AND (`effect1Id` = ?d OR `effect2Id` = ?d OR `effect3Id` = ?d)', + $areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ::zones WHERE `id` IN %in AND `parentArea` > 0', array_filter(array_column($quests, 'zone'))); + $qSpells = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `effect1Id`, `effect2Id`, `effect3Id`, `effect1TriggerSpell`, `effect2TriggerSpell`, `effect3TriggerSpell` FROM dbc_spell WHERE `id` IN %in AND (`effect1Id` = %i OR `effect2Id` = %i OR `effect3Id` = %i)', array_keys($quests), SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_LEARN_SPELL ); @@ -1166,7 +1166,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #6 Trainer', CLI::LOG_BLANK, true, true); - $tNpcs = DB::World()->select('SELECT `SpellID` AS ARRAY_KEY, cdt.`CreatureId` AS "entry", COUNT(1) AS "qty" FROM trainer_spell ts JOIN creature_default_trainer cdt ON cdt.`TrainerId` = ts.`TrainerId` GROUP BY ARRAY_KEY'); + $tNpcs = DB::World()->selectAssoc('SELECT `SpellID` AS ARRAY_KEY, cdt.`CreatureId` AS "entry", COUNT(1) AS "qty" FROM trainer_spell ts JOIN creature_default_trainer cdt ON cdt.`TrainerId` = ts.`TrainerId` GROUP BY ARRAY_KEY'); if (!$tNpcs) { CLI::write('[source] spelltrainer() - trainer_spell contained no spell or creature_default_trainer no trainer.', CLI::LOG_WARN); @@ -1175,7 +1175,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript // note: for consistency you could check for boss dummys and get the zone where the trainer resides, but seriously. Whats wrong with you‽ - $tSpells = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `effect1Id`, `effect2Id`, `effect3Id`, `effect1TriggerSpell`, `effect2TriggerSpell`, `effect3TriggerSpell` FROM dbc_spell WHERE `id` IN (?a)', array_keys($tNpcs)); + $tSpells = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `effect1Id`, `effect2Id`, `effect3Id`, `effect1TriggerSpell`, `effect2TriggerSpell`, `effect3TriggerSpell` FROM dbc_spell WHERE `id` IN %in', array_keys($tNpcs)); // todo (med): this skips some spells (e.g. riding) foreach ($tNpcs as $spellId => $npc) @@ -1206,7 +1206,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[source] * #7 Discovery', CLI::LOG_BLANK, true, true); // 61756: Northrend Inscription Research (FAST QA VERSION); - if ($disco = DB::World()->selectCol('SELECT `spellId` FROM skill_discovery_template WHERE `reqSpell` <> ?d', 61756)) + if ($disco = DB::World()->selectCol('SELECT `spellId` FROM skill_discovery_template WHERE `reqSpell` <> %i', 61756)) foreach ($disco as $d) $this->pushBuffer(Type::SPELL, $d, SRC_DISCOVERY); } @@ -1215,11 +1215,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #9 Talent', CLI::LOG_BLANK, true, true); - $tSpells = DB::Aowow()->select( + $tSpells = DB::Aowow()->selectAssoc( 'SELECT s.`id` AS ARRAY_KEY, s.`effect1Id`, s.`effect2Id`, s.`effect3Id`, s.`effect1TriggerSpell`, s.`effect2TriggerSpell`, s.`effect3TriggerSpell` FROM dbc_talent t JOIN dbc_spell s ON s.`id` = t.`rank1` - WHERE t.`rank2` < 1 AND (t.`talentSpell` = 1 OR (s.`effect1Id` = ?d OR s.`effect2Id` = ?d OR s.`effect3Id` = ?d))', + WHERE t.`rank2` < 1 AND (t.`talentSpell` = 1 OR (s.`effect1Id` = %i OR s.`effect2Id` = %i OR s.`effect3Id` = %i))', SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_LEARN_SPELL ); @@ -1245,7 +1245,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript if (!$recurse) break; - $tSpells = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `effect1Id`, `effect2Id`, `effect3Id`, `effect1TriggerSpell`, `effect2TriggerSpell`, `effect3TriggerSpell` FROM dbc_spell WHERE `id` IN (?a)', array_keys($recurse)); + $tSpells = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `effect1Id`, `effect2Id`, `effect3Id`, `effect1TriggerSpell`, `effect2TriggerSpell`, `effect3TriggerSpell` FROM dbc_spell WHERE `id` IN %in', array_keys($recurse)); } } @@ -1258,7 +1258,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[source] * #10 Starter', CLI::LOG_BLANK, true, true); $pcis = DB::World()->selectCol('SELECT DISTINCT `skill` FROM playercreateinfo_skills'); - $subSkills = DB::Aowow()->selectCol('SELECT `spellId` FROM dbc_skilllineability WHERE {(`skillLineId` IN (?a) AND `acquireMethod` = 2) OR} (`acquireMethod` = 1 AND (`reqSkillLevel` = 1 OR `skillLineId` = ?d)) GROUP BY `spellId`', $pcis ?: DBSIMPLE_SKIP, SKILL_FIRST_AID); + $subSkills = DB::Aowow()->selectCol('SELECT `spellId` FROM dbc_skilllineability WHERE %if', $pcis, '(`skillLineId` IN %in AND `acquireMethod` = 2) OR', $pcis, '%end (`acquireMethod` = 1 AND (`reqSkillLevel` = 1 OR `skillLineId` = %i)) GROUP BY `spellId`', SKILL_FIRST_AID); foreach ($subSkills as $s) $this->pushBuffer(Type::SPELL, $s, SRC_STARTER); } @@ -1267,13 +1267,13 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #4 Quest', CLI::LOG_BLANK, true, true); - $quests = DB::World()->select( + $quests = DB::World()->selectAssoc( 'SELECT `RewardTitle` AS ARRAY_KEY, `ID` AS "id", SUM(`qty`) AS "qty", BIT_OR(`side`) AS "side", IF(COUNT(DISTINCT `zone`) > 1, 0, `zone`) AS "zone" - FROM (SELECT `RewardTitle`, `ID`, 1 AS "qty", IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, IF(`AllowableRaces` & ?d AND NOT (`AllowableRaces` & ?d), ?d, ?d)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardTitle` > 0) q - { WHERE q.`Id` NOT IN (?a) } + FROM (SELECT `RewardTitle`, `ID`, 1 AS "qty", IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, IF(`AllowableRaces` & %i AND NOT (`AllowableRaces` & %i), %i, %i)) AS "side", GREATEST(`QuestSortID`, 0) AS "zone" FROM quest_template WHERE `RewardTitle` > 0) q + WHERE q.`Id` NOT IN %in GROUP BY `RewardTitle`', ChrRace::MASK_HORDE, ChrRace::MASK_ALLIANCE, SIDE_HORDE, ChrRace::MASK_ALLIANCE, ChrRace::MASK_HORDE, SIDE_ALLIANCE, SIDE_BOTH, - !empty($this->disables[Type::QUEST]) ? array_values($this->disables[Type::QUEST]) : DBSIMPLE_SKIP + $this->disables[Type::QUEST] ?? [0] ); if (!$quests) @@ -1282,7 +1282,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript return; } - $areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ?_zones WHERE `id` IN (?a) AND parentArea > 0', array_filter(array_column($quests, 'zone'))); + $areaParent = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, `parentArea` FROM ::zones WHERE `id` IN %in AND parentArea > 0', array_filter(array_column($quests, 'zone'))); foreach ($quests as $titleId => $q) $this->pushBuffer(Type::TITLE, $titleId, SRC_QUEST, $q['side'], $q['qty'] > 1 ? 0 : Type::QUEST, $q['id'], $areaParent[$q['zone']] ?? Game::$questSortFix[$q['zone']] ?? $q['zone']); @@ -1292,7 +1292,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript { CLI::write('[source] * #12 Achievement', CLI::LOG_BLANK, true, true); - $sets = DB::World()->select( + $sets = DB::World()->selectAssoc( 'SELECT `titleId` AS ARRAY_KEY, MIN(`ID`) AS "srcId", NULLIF(MAX(`ID`), MIN(`ID`)) AS "altSrcId" FROM (SELECT `TitleA` AS "titleId", `ID` FROM achievement_reward WHERE `TitleA` <> 0 UNION SELECT `TitleH` AS "titleId", `ID` FROM achievement_reward WHERE `TitleH` <> 0) AS x @@ -1304,7 +1304,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript $this->pushBuffer(Type::TITLE, $tId, SRC_ACHIEVEMENT, 1, Type::ACHIEVEMENT, $set['srcId']); if ($set['altSrcId']) - DB::Aowow()->query('UPDATE ?_titles SET src12Ext = ?d WHERE id = ?d', $set['altSrcId'], $tId); + DB::Aowow()->qry('UPDATE ::titles SET src12Ext = %i WHERE id = %i', $set['altSrcId'], $tId); } } @@ -1318,9 +1318,9 @@ CLISetup::registerSetup("sql", new class extends SetupScript private function itemset() : void { - // every item in ?_itemset needs a source. if so merge fields. if not it's not available. + // every item in ::itemset needs a source. if so merge fields. if not it's not available. - $sets = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `contentGroup`, `item1`, `item2`, `item3`, `item4`, `item5`, `item6`, `item7`, `item8`, `item9`, `item10` FROM ?_itemset'); + $sets = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `contentGroup`, `item1`, `item2`, `item3`, `item4`, `item5`, `item6`, `item7`, `item8`, `item9`, `item10` FROM ::itemset'); $metaSrc = []; foreach ($sets as $id => $set) diff --git a/setup/tools/sqlgen/spawns.ss.php b/setup/tools/sqlgen/spawns.ss.php index 5e8182f1..e6ccd4a2 100644 --- a/setup/tools/sqlgen/spawns.ss.php +++ b/setup/tools/sqlgen/spawns.ss.php @@ -27,8 +27,10 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $worldDependency = ['creature', 'creature_addon', 'creature_template_addon', 'gameobject', 'gameobject_template', 'vehicle_accessory', 'vehicle_accessory_template', 'waypoint_data', 'smart_scripts', 'areatrigger_teleport']; protected $setupAfter = [['dungeonmap', 'worldmaparea', 'zones'], ['img-maps']]; - private $transports = []; - private $overrideData = []; + private array $transports = []; + private array $overrideData = []; + private array $mapToArea = []; + private array $areaParents = []; private $steps = array( 0x01 => ['creature', Type::NPC, false, '`creature` spawns', ], @@ -40,7 +42,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript ); - public function generate(array $ids = []) : bool + public function generate() : bool { /*****************************/ /* find out what to generate */ @@ -74,30 +76,32 @@ CLISetup::registerSetup("sql", new class extends SetupScript /*********************************/ if (!$todoMask || ($todoMask & 0x1F) == 0x1F) - DB::Aowow()->query('TRUNCATE TABLE ?_spawns'); + DB::Aowow()->qry('TRUNCATE TABLE ::spawns'); else foreach ($this->steps as $idx => [, $type, $isWP, ]) if (($idx & $todoMask) && !$isWP) - DB::Aowow()->query('DELETE FROM ?_spawns WHERE `type` = ?d', $type); + DB::Aowow()->qry('DELETE FROM ::spawns WHERE `type` = %i', $type); if (!$todoMask || ($todoMask & 0x20)) - DB::Aowow()->query('TRUNCATE TABLE ?_creature_waypoints'); + DB::Aowow()->qry('TRUNCATE TABLE ::creature_waypoints'); /**************************/ /* offsets for transports */ /**************************/ - $this->transports = DB::World()->selectCol('SELECT `data0` AS `pathId`, `data6` AS ARRAY_KEY FROM gameobject_template WHERE `type` = ?d AND `data6` <> 0', OBJECT_MO_TRANSPORT); + $this->transports = DB::World()->selectCol('SELECT `data0` AS `pathId`, `data6` AS ARRAY_KEY FROM gameobject_template WHERE `type` = %i AND `data6` <> 0', OBJECT_MO_TRANSPORT); foreach ($this->transports as &$t) - $t = DB::Aowow()->selectRow('SELECT `posX`, `posY`, `mapId` FROM dbc_taxipathnode tpn WHERE tpn.`pathId` = ?d AND `nodeIdx` = 0', $t); + $t = DB::Aowow()->selectRow('SELECT `posX`, `posY`, `mapId` FROM dbc_taxipathnode tpn WHERE tpn.`pathId` = %i AND `nodeIdx` = 0', $t); /*********************/ /* get override data */ /*********************/ - $this->overrideData = DB::Aowow()->select('SELECT `type` AS ARRAY_KEY, `typeGuid` AS ARRAY_KEY2, `areaId`, `floor` FROM ?_spawns_override'); + $this->overrideData = DB::Aowow()->selectAssoc('SELECT `type` AS ARRAY_KEY, `typeGuid` AS ARRAY_KEY2, `areaId`, `floor` FROM ::spawns_override'); + $this->mapToArea = DB::Aowow()->selectCol('SELECT `mapId` AS ARRAY_KEY, `id` FROM ::zones WHERE `parentArea` = 0 AND (`cuFlags` & %i) = 0', CUSTOM_EXCLUDE_FOR_LISTVIEW); + $this->areaParents = DB::Aowow()->selectCol('SELECT `id` AS ARRAY_KEY, IF(`parentArea`, `parentArea`, `id`) FROM ::zones'); /**************/ @@ -109,6 +113,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript $time = new Timer(500); $sum = 0; $lastOverride = 0; + $insertData = []; $nSteps = count($this->steps); $queryResult = $this->$generator(); $queryTotal = count($queryResult); @@ -139,16 +144,28 @@ CLISetup::registerSetup("sql", new class extends SetupScript continue; } - $set = array_merge($spawn, $point); - if (!$isWP) // REPLACE: because there is bogus data where one path may be assigned to multiple npcs + [ + $insertData['areaId'][], + $insertData['posX'][], + $insertData['posY'][], + $insertData['floor'][] + ] = $point; // [areaId, posX, posY, floor] + + unset($spawn['map'], $spawn['posX'], $spawn['posY'], $spawn['areaId']); + foreach ($spawn as $k => $v) + $insertData[$k][] = $v; + + if (!($sum % 1000) || $sum == $queryTotal) { - unset($set['map']); - DB::Aowow()->query('REPLACE INTO ?_spawns (?#) VALUES (?a)', array_keys($set), array_values($set)); - } - else - { - unset($set['map'], $set['guid']); - DB::Aowow()->query('REPLACE INTO ?_creature_waypoints (?#) VALUES (?a)', array_keys($set), array_values($set)); + if (!$isWP) // REPLACE: because there is bogus data where one path may be assigned to multiple npcs + DB::Aowow()->qry('REPLACE INTO ::spawns %m', $insertData); + else + { + unset($insertData['guid']); + DB::Aowow()->qry('REPLACE INTO ::creature_waypoints %m', $insertData); + } + + $insertData = []; } } } @@ -161,7 +178,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript if ($todoMask & 0x01) // only when creature is set { // get vehicle template accessories - $accessories = DB::World()->select( + $accessories = DB::World()->selectAssoc( 'SELECT vta.`accessory_entry` AS `typeId`, c.`guid`, vta.`entry`, COUNT(1) AS `nSeats` FROM vehicle_template_accessory vta LEFT JOIN creature c ON c.`id` = vta.`entry` GROUP BY `accessory_entry`, c.`guid` UNION SELECT va.`accessory_entry` AS `typeId`, va.`guid`, 0 AS `entry`, COUNT(1) AS `nSeats` FROM vehicle_accessory va GROUP BY `accessory_entry`, va.`guid`' ); @@ -178,16 +195,16 @@ CLISetup::registerSetup("sql", new class extends SetupScript { $vehicles = []; if ($data['guid']) // vehicle already spawned - $vehicles = DB::Aowow()->select('SELECT s.`areaId`, s.`posX`, s.`posY`, s.`floor` FROM ?_spawns s WHERE s.`guid` = ?d AND s.`type` = ?d', $data['guid'], Type::NPC); + $vehicles = DB::Aowow()->selectAssoc('SELECT s.`areaId`, s.`posX`, s.`posY`, s.`floor` FROM ::spawns s WHERE s.`guid` = %i AND s.`type` = %i', $data['guid'], Type::NPC); else if ($data['entry']) // vehicle on unspawned vehicle action - $vehicles = DB::Aowow()->select('SELECT s.`areaId`, s.`posX`, s.`posY`, s.`floor` FROM ?_spawns s WHERE s.`typeId` = ?d AND s.`type` = ?d', $data['entry'], Type::NPC); + $vehicles = DB::Aowow()->selectAssoc('SELECT s.`areaId`, s.`posX`, s.`posY`, s.`floor` FROM ::spawns s WHERE s.`typeId` = %i AND s.`type` = %i', $data['entry'], Type::NPC); if ($vehicles) { $matches++; foreach ($vehicles as $v) // if there is more than one vehicle, its probably due to overlapping zones for ($i = 0; $i < $data['nSeats']; $i++) - DB::Aowow()->query('INSERT INTO ?_spawns (`guid`, `type`, `typeId`, `respawn`, `spawnMask`, `phaseMask`, `areaId`, `floor`, `posX`, `posY`, `pathId`) VALUES (?d, ?d, ?d, 0, 0, 1, ?d, ?d, ?f, ?f, 0)', + DB::Aowow()->qry('INSERT INTO ::spawns (`guid`, `type`, `typeId`, `respawn`, `spawnMask`, `phaseMask`, `areaId`, `floor`, `posX`, `posY`, `pathId`) VALUES (%i, %i, %i, 0, 0, 1, %i, %i, %f, %f, 0)', --$vGuid, Type::NPC, $data['typeId'], $v['areaId'], $v['floor'], $v['posX'], $v['posY']); unset($accessories[$idx]); @@ -205,7 +222,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript /* restrict difficulty displays */ /********************************/ - DB::Aowow()->query('UPDATE ?_spawns s, dbc_worldmaparea wma, dbc_map m SET s.`spawnMask` = 0 WHERE s.`areaId` = wma.`areaId` AND wma.`mapId` = m.`id` AND m.`areaType` IN (0, 3, 4)'); + DB::Aowow()->qry('UPDATE ::spawns s, dbc_worldmaparea wma, dbc_map m SET s.`spawnMask` = 0 WHERE s.`areaId` = wma.`areaId` AND wma.`mapId` = m.`id` AND m.`areaType` IN (0, 3, 4)'); return true; } @@ -213,8 +230,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript private function creature() : array { // [guid, type, typeId, map, posX, posY [, respawn, spawnMask, phaseMask, areaId, floor, pathId, ScriptName, StringId]] - return DB::World()->select( - 'SELECT c.`guid`, ?d AS `type`, c.`id` AS `typeId`, c.`map`, c.`position_x` AS `posX`, c.`position_y` AS `posY`, c.`spawntimesecs` AS `respawn`, c.`spawnMask`, c.`phaseMask`, c.`zoneId` AS `areaId`, IFNULL(ca.`path_id`, IFNULL(cta.`path_id`, 0)) AS `pathId`, NULLIF(`ScriptName`, "") AS "ScriptName", NULLIF(`StringId`, "") AS "StringId" + return DB::World()->selectAssoc( + 'SELECT c.`guid`, %i AS `type`, c.`id` AS `typeId`, c.`map`, c.`position_x` AS `posX`, c.`position_y` AS `posY`, c.`spawntimesecs` AS `respawn`, c.`spawnMask`, c.`phaseMask`, c.`zoneId` AS `areaId`, IFNULL(ca.`path_id`, IFNULL(cta.`path_id`, 0)) AS `pathId`, NULLIF(`ScriptName`, "") AS "ScriptName", NULLIF(`StringId`, "") AS "StringId" FROM creature c LEFT JOIN creature_addon ca ON ca.guid = c.guid LEFT JOIN creature_template_addon cta ON cta.entry = c.id', @@ -225,8 +242,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript private function gameobject() : array { // [guid, type, typeId, map, posX, posY [, respawn, spawnMask, phaseMask, areaId, floor, pathId, ScriptName, StringId]] - return DB::World()->select( - 'SELECT `guid`, ?d AS `type`, `id` AS `typeId`, `map`, `position_x` AS `posX`, `position_y` AS `posY`, `spawntimesecs` AS `respawn`, `spawnMask`, `phaseMask`, `zoneId` AS `areaId`, NULLIF(`ScriptName`, "") AS "ScriptName", NULLIF(`StringId`, "") AS "StringId" + return DB::World()->selectAssoc( + 'SELECT `guid`, %i AS `type`, `id` AS `typeId`, `map`, `position_x` AS `posX`, `position_y` AS `posY`, `spawntimesecs` AS `respawn`, `spawnMask`, `phaseMask`, `zoneId` AS `areaId`, NULLIF(`ScriptName`, "") AS "ScriptName", NULLIF(`StringId`, "") AS "StringId" FROM gameobject', Type::OBJECT ); @@ -235,8 +252,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript private function soundemitter() : array { // [guid, type, typeId, map, posX, posY [, respawn, spawnMask, phaseMask, areaId, floor, pathId, ScriptName, StringId]] - return DB::Aowow()->select( - 'SELECT `id` AS `guid`, ?d AS `type`, `soundId` AS `typeId`, `mapId` AS `map`, `posX`, `posY` + return DB::Aowow()->selectAssoc( + 'SELECT `id` AS `guid`, %i AS `type`, `soundId` AS `typeId`, `mapId` AS `map`, `posX`, `posY` FROM dbc_soundemitters', Type::SOUND ); @@ -245,18 +262,18 @@ CLISetup::registerSetup("sql", new class extends SetupScript private function areatrigger() : array { // [guid, type, typeId, map, posX, posY [, respawn, spawnMask, phaseMask, areaId, floor, pathId, ScriptName, StringId]] - $base = DB::Aowow()->select( - 'SELECT `id` AS `guid`, ?d AS `type`, `id` AS `typeId`, `mapId` AS `map`, `posX`, `posY` + $base = DB::Aowow()->selectAssoc( + 'SELECT `id` AS `guid`, %i AS `type`, `id` AS `typeId`, `mapId` AS `map`, `posX`, `posY` FROM dbc_areatrigger', Type::AREATRIGGER ); - $addData = DB::World()->select( - 'SELECT -`ID` AS `guid`, ?d AS `type`, ID AS `typeId`, `target_map` AS `map`, `target_position_x` AS `posX`, `target_position_y` AS `posY` + $addData = DB::World()->selectAssoc( + 'SELECT -`ID` AS `guid`, %i AS `type`, ID AS `typeId`, `target_map` AS `map`, `target_position_x` AS `posX`, `target_position_y` AS `posY` FROM areatrigger_teleport UNION - SELECT -`entryorguid` AS `guid`, ?d AS `type`, entryorguid AS `typeId`, `action_param1` AS `map`, `target_x` AS `posX`, `target_y` AS `posY` + SELECT -`entryorguid` AS `guid`, %i AS `type`, entryorguid AS `typeId`, `action_param1` AS `map`, `target_x` AS `posX`, `target_y` AS `posY` FROM smart_scripts - WHERE `source_type` = ?d AND `action_type` = ?d', + WHERE `source_type` = %i AND `action_type` = %i', Type::AREATRIGGER, Type::AREATRIGGER, SmartAI::SRC_TYPE_AREATRIGGER, SmartAction::ACTION_TELEPORT ); @@ -266,10 +283,10 @@ CLISetup::registerSetup("sql", new class extends SetupScript private function instances() : array { // maps with set graveyard - return DB::Aowow()->select( - 'SELECT -`id` AS `guid`, ?d AS `type`, `id` AS `typeId`, `parentMapId` AS `map`, `parentX` AS `posX`, `parentY` AS `posY` - FROM ?_zones - WHERE `parentX` <> 0 AND `parentY` <> 0 AND `parentArea` = 0 AND (`cuFlags` & ?d) = 0', + return DB::Aowow()->selectAssoc( + 'SELECT -`id` AS `guid`, %i AS `type`, `id` AS `typeId`, `parentMapId` AS `map`, `parentX` AS `posX`, `parentY` AS `posY` + FROM ::zones + WHERE `parentX` <> 0 AND `parentY` <> 0 AND `parentArea` = 0 AND (`cuFlags` & %i) = 0', Type::ZONE, CUSTOM_EXCLUDE_FOR_LISTVIEW ); } @@ -280,7 +297,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript // in the future guid should be optional and additional parameters substituting guid should be passed down from NpcPage after SmartAI has been evaluated // assume that creature_template_addon data isn't stupid and only creatures with a single spawn are referenced here - return DB::World()->select( + return DB::World()->selectAssoc( 'SELECT c.`guid`, -w.`id` AS `creatureOrPath`, w.`point`, c.`zoneId` AS `areaId`, c.`map`, w.`delay` AS `wait`, w.`position_x` AS `posX`, w.`position_y` AS `posY` FROM creature c JOIN creature_addon ca ON ca.`guid` = c.`guid` @@ -294,7 +311,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript ); } - private function transformPoint(array $point, int $type, ?string &$notice = '') : array + private function transformPoint(array $point, int $type, ?string &$notice = '') : ?array { // npc/object is on a transport -> apply offsets to path of transport // note, that transport DO spawn outside of displayable area maps .. another todo i guess.. @@ -318,22 +335,21 @@ CLISetup::registerSetup("sql", new class extends SetupScript { // if areaId is set and we match it .. we're fine .. mostly if (count($points) == 1 && $area == $points[0]['areaId']) - return ['areaId' => $points[0]['areaId'], 'posX' => $points[0]['posX'], 'posY' => $points[0]['posY'], 'floor' => $points[0]['floor']]; + return [$points[0]['areaId'], $points[0]['posX'], $points[0]['posY'], $points[0]['floor']]; $point = WorldPosition::checkZonePos($points); // try to determine best found point by alphamap - return ['areaId' => $point['areaId'], 'posX' => $point['posX'], 'posY' => $point['posY'], 'floor' => $point['floor']]; + return [$point['areaId'], $point['posX'], $point['posY'], $point['floor']]; } // cannot be placed on a map, try to reuse TC assigned areaId (note: area has been invalid in the past) - if ($area && ($selfOrParent = DB::Aowow()->selectCell('SELECT IF(`parentArea`, `parentArea`, `id`) FROM ?_zones WHERE `id` = ?d', $area))) - return ['areaId' => $selfOrParent, 'posX' => 0, 'posY' => 0, 'floor' => 0]; + if ($area && isset($this->areaParents[$area])) + return [$this->areaParents[$area], 0, 0, 0]; // we know the instanced map; try to assign a zone this way - if (!in_array($point['map'], [0, 1, 530, 571])) - if ($area = DB::Aowow()->selectCell('SELECT `id` FROM ?_zones WHERE `mapId` = ?d AND `parentArea` = 0 AND (`cuFlags` & ?d) = 0', $point['map'], CUSTOM_EXCLUDE_FOR_LISTVIEW)) - return ['areaId' => $area, 'posX' => 0, 'posY' => 0, 'floor' => 0]; + if (!in_array($point['map'], [0, 1, 530, 571]) && isset($this->mapToArea[$point['map']])) + return [$this->mapToArea[$point['map']], 0, 0, 0]; - return []; + return null; } }); diff --git a/setup/tools/sqlgen/spell.ss.php b/setup/tools/sqlgen/spell.ss.php index 9ecab5df..14dcba03 100644 --- a/setup/tools/sqlgen/spell.ss.php +++ b/setup/tools/sqlgen/spell.ss.php @@ -21,14 +21,14 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $worldDependency = ['item_template', 'creature_template', 'creature_template_addon', 'creature_template_spell', 'smart_scripts', 'trainer_spell', 'disables', 'spell_ranks', 'spell_dbc', 'skill_discovery_template']; protected $setupAfter = [['icons', 'spellrange'], []]; // spellrange required to use SpellList - public function generate(array $ids = []) : bool + public function generate() : bool { $ssQuery = 'SELECT id, 0 AS category, Dispel, Mechanic, Attributes, AttributesEx, AttributesEx2, AttributesEx3, AttributesEx4, AttributesEx5, AttributesEx6, AttributesEx7, - ?d AS cuFlags, + %i AS cuFlags, 0 AS typeCat, Stances, StancesNot, Targets, @@ -105,7 +105,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript 0 AS spellDescriptionVariable, 0 AS trainingCost FROM spell_dbc - LIMIT ?d,?d'; + LIMIT %i,%i'; $baseQry = 'SELECT s.id, category, @@ -195,17 +195,17 @@ CLISetup::registerSetup("sql", new class extends SetupScript LEFT JOIN dbc_spellradius sr1 ON s.effect1RadiusId = sr1.id LEFT JOIN dbc_spellradius sr2 ON s.effect2RadiusId = sr2.id LEFT JOIN dbc_spellradius sr3 ON s.effect3RadiusId = sr3.id - LIMIT ?d,?d'; + LIMIT %i,%i'; - DB::Aowow()->query('TRUNCATE ?_spell'); - DB::Aowow()->query('SET SESSION innodb_ft_enable_stopword = OFF'); + DB::Aowow()->qry('TRUNCATE ::spell'); + DB::Aowow()->qry('SET SESSION innodb_ft_enable_stopword = OFF'); // merge serverside spells into aowow_spell $lastMax = 0; $n = 0; CLI::write('[spell] - copying serverside spells into aowow_spell'); - while ($spells = DB::World()->select($ssQuery, CUSTOM_SERVERSIDE, $n++ * CLISetup::SQL_BATCH, CLISetup::SQL_BATCH)) + while ($spells = DB::World()->selectAssoc($ssQuery, CUSTOM_SERVERSIDE, $n++ * CLISetup::SQL_BATCH, CLISetup::SQL_BATCH)) { $newMax = max(array_column($spells, 'id')); @@ -214,21 +214,21 @@ CLISetup::registerSetup("sql", new class extends SetupScript $lastMax = $newMax; foreach ($spells as $spell) - DB::Aowow()->query('INSERT INTO ?_spell VALUES (?a)', array_values($spell)); + DB::Aowow()->qry('INSERT INTO ::spell VALUES %l', $spell); } // apply spell radii, duration & casting time - DB::Aowow()->query('UPDATE ?_spell s LEFT JOIN dbc_spellradius sr ON s.`effect1RadiusMin` = sr.`id` SET s.`effect1RadiusMin` = IFNULL(sr.`radiusMin`, 0), s.`effect1RadiusMax` = IFNULL(sr.`radiusMax`, 0)'); - DB::Aowow()->query('UPDATE ?_spell s LEFT JOIN dbc_spellradius sr ON s.`effect2RadiusMin` = sr.`id` SET s.`effect2RadiusMin` = IFNULL(sr.`radiusMin`, 0), s.`effect2RadiusMax` = IFNULL(sr.`radiusMax`, 0)'); - DB::Aowow()->query('UPDATE ?_spell s LEFT JOIN dbc_spellradius sr ON s.`effect3RadiusMin` = sr.`id` SET s.`effect3RadiusMin` = IFNULL(sr.`radiusMin`, 0), s.`effect3RadiusMax` = IFNULL(sr.`radiusMax`, 0)'); - DB::Aowow()->query('UPDATE ?_spell s LEFT JOIN dbc_spellduration sd ON s.`duration` = sd.`id` SET s.`duration` = IF(sd.`baseTime` iS NULL, -1, IF(sd.`baseTime` <> -1, ABS(sd.`baseTime`), -1))'); - DB::Aowow()->query('UPDATE ?_spell s LEFT JOIN dbc_spellcasttimes sct ON s.`castTime` = sct.`id` SET s.`castTime` = GREATEST(IFNULL(sct.`baseTime`, 0), 0) / 1000'); + DB::Aowow()->qry('UPDATE ::spell s LEFT JOIN dbc_spellradius sr ON s.`effect1RadiusMin` = sr.`id` SET s.`effect1RadiusMin` = IFNULL(sr.`radiusMin`, 0), s.`effect1RadiusMax` = IFNULL(sr.`radiusMax`, 0)'); + DB::Aowow()->qry('UPDATE ::spell s LEFT JOIN dbc_spellradius sr ON s.`effect2RadiusMin` = sr.`id` SET s.`effect2RadiusMin` = IFNULL(sr.`radiusMin`, 0), s.`effect2RadiusMax` = IFNULL(sr.`radiusMax`, 0)'); + DB::Aowow()->qry('UPDATE ::spell s LEFT JOIN dbc_spellradius sr ON s.`effect3RadiusMin` = sr.`id` SET s.`effect3RadiusMin` = IFNULL(sr.`radiusMin`, 0), s.`effect3RadiusMax` = IFNULL(sr.`radiusMax`, 0)'); + DB::Aowow()->qry('UPDATE ::spell s LEFT JOIN dbc_spellduration sd ON s.`duration` = sd.`id` SET s.`duration` = IF(sd.`baseTime` iS NULL, -1, IF(sd.`baseTime` <> -1, ABS(sd.`baseTime`), -1))'); + DB::Aowow()->qry('UPDATE ::spell s LEFT JOIN dbc_spellcasttimes sct ON s.`castTime` = sct.`id` SET s.`castTime` = GREATEST(IFNULL(sct.`baseTime`, 0), 0) / 1000'); // merge spell.dbc into aowow_spell $lastMax = 0; $n = 0; CLI::write('[spell] - merging spell.dbc into aowow_spell'); - while ($spells = DB::Aowow()->select($baseQry, $n++ * CLISetup::SQL_BATCH, CLISetup::SQL_BATCH)) + while ($spells = DB::Aowow()->selectAssoc($baseQry, $n++ * CLISetup::SQL_BATCH, CLISetup::SQL_BATCH)) { $newMax = max(array_column($spells, 'id')); @@ -237,26 +237,26 @@ CLISetup::registerSetup("sql", new class extends SetupScript $lastMax = $newMax; foreach ($spells as $spell) - DB::Aowow()->query('INSERT INTO ?_spell VALUES (?a)', array_values($spell)); + DB::Aowow()->qry('INSERT INTO ::spell VALUES %l', $spell); } // apply flag: CUSTOM_DISABLED [0xD: players (0x1), pets (0x4), general (0x8); only generally disabled spells] if ($disables = DB::World()->selectCol('SELECT `entry` FROM disables WHERE `sourceType` = 0 AND `params_0` = "" AND `params_1` = "" AND `flags` & 0xD')) - DB::Aowow()->query('UPDATE ?_spell SET `cuFlags` = `cuFlags` | ?d WHERE `id` IN (?a)', CUSTOM_DISABLED, $disables); + DB::Aowow()->qry('UPDATE ::spell SET `cuFlags` = `cuFlags` | %i WHERE `id` IN %in', CUSTOM_DISABLED, $disables); // apply spell ranks (can't use skilllineability.dbc, as it does not contain ranks for non-player/pet spells) $ranks = DB::World()->selectCol('SELECT `first_spell_id` AS ARRAY_KEY, `spell_id` AS ARRAY_KEY2, `rank` FROM spell_ranks'); foreach ($ranks as $firstSpell => $sets) { // apply flag: SPELL_CU_FIRST_RANK - DB::Aowow()->query('UPDATE ?_spell SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', SPELL_CU_FIRST_RANK, $firstSpell); + DB::Aowow()->qry('UPDATE ::spell SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', SPELL_CU_FIRST_RANK, $firstSpell); foreach ($sets as $spell => $rank) - DB::Aowow()->query('UPDATE ?_spell SET `rankNo` = ?d WHERE `id` = ?d', $rank, $spell); + DB::Aowow()->qry('UPDATE ::spell SET `rankNo` = %i WHERE `id` = %i', $rank, $spell); // apply flag: SPELL_CU_LAST_RANK end($sets); - DB::Aowow()->query('UPDATE ?_spell SET `cuFlags` = `cuFlags` | ?d WHERE `id` = ?d', SPELL_CU_LAST_RANK, key($sets)); + DB::Aowow()->qry('UPDATE ::spell SET `cuFlags` = `cuFlags` | %i WHERE `id` = %i', SPELL_CU_LAST_RANK, key($sets)); } @@ -271,7 +271,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[spell] - linking with skilllineability'); - $results = DB::Aowow()->select('SELECT `spellId` AS ARRAY_KEY, `id` AS ARRAY_KEY2, `skillLineId`, `reqRaceMask`, `reqClassMask`, `reqSkillLevel`, `acquireMethod`, `skillLevelGrey`, `skillLevelYellow` FROM dbc_skilllineability sla'); + $results = DB::Aowow()->selectAssoc('SELECT `spellId` AS ARRAY_KEY, `id` AS ARRAY_KEY2, `skillLineId`, `reqRaceMask`, `reqClassMask`, `reqSkillLevel`, `acquireMethod`, `skillLevelGrey`, `skillLevelYellow` FROM dbc_skilllineability sla'); foreach ($results as $spellId => $sets) { $names = array_keys(current($sets)); @@ -320,7 +320,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript } if ($trainer) - DB::Aowow()->query('UPDATE ?_spell SET `learnedAt` = 1 WHERE `id` = ?d', $spellId); + DB::Aowow()->qry('UPDATE ::spell SET `learnedAt` = 1 WHERE `id` = %i', $spellId); // check skillLineId against mask switch (count($lines)) @@ -344,13 +344,13 @@ CLISetup::registerSetup("sql", new class extends SetupScript } } - DB::Aowow()->query('UPDATE ?_spell SET ?a WHERE `id` = ?d', $update, $spellId); + DB::Aowow()->qry('UPDATE ::spell SET %a WHERE `id` = %i', $update, $spellId); } // fill learnedAt, trainingCost from trainer - if ($trainer = DB::World()->select('SELECT `spellID` AS ARRAY_KEY, MIN(`ReqSkillRank`) AS `reqSkill`, MIN(`MoneyCost`) AS `cost`, `ReqAbility1` AS `reqSpellId`, COUNT(*) AS `count` FROM trainer_spell GROUP BY `SpellID`')) + if ($trainer = DB::World()->selectAssoc('SELECT `spellID` AS ARRAY_KEY, MIN(`ReqSkillRank`) AS `reqSkill`, MIN(`MoneyCost`) AS `cost`, `ReqAbility1` AS `reqSpellId`, COUNT(*) AS `count` FROM trainer_spell GROUP BY `SpellID`')) { - $spells = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `effect1Id`, `effect2Id`, `effect3Id`, `effect1TriggerSpell`, `effect2TriggerSpell`, `effect3TriggerSpell` FROM dbc_spell WHERE `id` IN (?a)', array_keys($trainer)); + $spells = DB::Aowow()->selectAssoc('SELECT `id` AS ARRAY_KEY, `effect1Id`, `effect2Id`, `effect3Id`, `effect1TriggerSpell`, `effect2TriggerSpell`, `effect3TriggerSpell` FROM dbc_spell WHERE `id` IN %in', array_keys($trainer)); $links = []; // todo (med): this skips some spells (e.g. riding) @@ -397,14 +397,14 @@ CLISetup::registerSetup("sql", new class extends SetupScript } foreach ($links as $spell => $link) - DB::Aowow()->query("UPDATE ?_spell s SET s.`learnedAt` = ?d, s.`trainingCost` = ?d WHERE s.`id` = ?d", $link[0], $link[1], $spell); + DB::Aowow()->qry("UPDATE ::spell s SET s.`learnedAt` = %i, s.`trainingCost` = %i WHERE s.`id` = %i", $link[0], $link[1], $spell); } // fill learnedAt from recipe-items - $recipes = DB::World()->selectCol('SELECT IF(`spelltrigger_2` = ?d, `spellid_2`, `spellid_1`) AS ARRAY_KEY, MIN(`RequiredSkillRank`) FROM item_template WHERE `class` = ?d AND `spelltrigger_1` <> ?d AND `RequiredSkillRank` > 0 GROUP BY ARRAY_KEY', + $recipes = DB::World()->selectCol('SELECT IF(`spelltrigger_2` = %i, `spellid_2`, `spellid_1`) AS ARRAY_KEY, MIN(`RequiredSkillRank`) FROM item_template WHERE `class` = %i AND `spelltrigger_1` <> %i AND `RequiredSkillRank` > 0 GROUP BY ARRAY_KEY', SPELL_TRIGGER_LEARN, ITEM_CLASS_RECIPE, SPELL_TRIGGER_EQUIP); foreach ($recipes as $spell => $reqSkill) - DB::Aowow()->query('UPDATE ?_spell SET `learnedAt` = IF(`learnedAt` = 0 OR `learnedAt` > ?d, ?d, `learnedAt`) WHERE `id` = ?d', $reqSkill, $reqSkill, $spell); + DB::Aowow()->qry('UPDATE ::spell SET `learnedAt` = IF(`learnedAt` = 0 OR `learnedAt` > %i, %i, `learnedAt`) WHERE `id` = %i', $reqSkill, $reqSkill, $spell); // fill learnedAt from Discovery // 61756: Northrend Inscription Research (FAST QA VERSION); @@ -412,20 +412,20 @@ CLISetup::registerSetup("sql", new class extends SetupScript // 28571 - 28576: $element Protection Potion (todo: get reqSkill from teaching spell [360]) $discovery = DB::World()->selectCol( 'SELECT `spellId` AS ARRAY_KEY, - IF(`reqSpell` = ?d, ?d, - IF(`reqSpell` BETWEEN ?d AND ?d, ?d, + IF(`reqSpell` = %i, %i, + IF(`reqSpell` BETWEEN %i AND %i, %i, IF(`reqSkillValue`, `reqSkillValue`, 1))) FROM skill_discovery_template - WHERE `reqSpell` NOT IN (?a)', + WHERE `reqSpell` NOT IN %in', 64323, 425, 28571, 28576, 360, [61756] ); foreach ($discovery as $spell => $reqSkill) - DB::Aowow()->query('UPDATE ?_spell SET `learnedAt` = ?d WHERE `id` = ?d', $reqSkill, $spell); + DB::Aowow()->qry('UPDATE ::spell SET `learnedAt` = %i WHERE `id` = %i', $reqSkill, $spell); // calc reqSkill for gathering-passives (herbing, mining, skinning) (on second thought .. it is set in skilllineability >.<) - $sets = DB::World()->selectCol('SELECT `spell_id` AS ARRAY_KEY, `rank` * 75 AS `reqSkill` FROM spell_ranks WHERE `first_spell_id` IN (?a)', [55428, 53120, 53125]); + $sets = DB::World()->selectCol('SELECT `spell_id` AS ARRAY_KEY, `rank` * 75 AS `reqSkill` FROM spell_ranks WHERE `first_spell_id` IN %in', [55428, 53120, 53125]); foreach ($sets as $spell => $reqSkill) - DB::Aowow()->query('UPDATE ?_spell SET `learnedAt` = ?d WHERE `id` = ?d', $reqSkill, $spell); + DB::Aowow()->qry('UPDATE ::spell SET `learnedAt` = %i WHERE `id` = %i', $reqSkill, $spell); /******************/ @@ -437,16 +437,16 @@ CLISetup::registerSetup("sql", new class extends SetupScript for ($i = 1; $i < 6; $i++) { // classMask - DB::Aowow()->query('UPDATE ?_spell s, dbc_talent t, dbc_talenttab tt SET s.`reqClassMask` = tt.`classMask` WHERE tt.`creatureFamilyMask` = 0 AND tt.`id` = t.`tabId` AND t.?# = s.`id`', 'rank'.$i); + DB::Aowow()->qry('UPDATE ::spell s, dbc_talent t, dbc_talenttab tt SET s.`reqClassMask` = tt.`classMask` WHERE tt.`creatureFamilyMask` = 0 AND tt.`id` = t.`tabId` AND t.%n = s.`id`', 'rank'.$i); // talentLevel - DB::Aowow()->query('UPDATE ?_spell s, dbc_talent t, dbc_talenttab tt SET s.`talentLevel` = (t.`row` * 5) + 10 + (?d * 1) WHERE tt.`id` = t.`tabId` AND tt.`creatureFamilyMask` = 0 AND t.?# = s.`id`', $i - 1, 'rank'.$i); - DB::Aowow()->query('UPDATE ?_spell s, dbc_talent t, dbc_talenttab tt SET s.`talentLevel` = (t.`row` * 12) + 20 + (?d * 4) WHERE tt.`id` = t.`tabId` AND tt.`creatureFamilyMask` <> 0 AND t.?# = s.`id`', $i - 1, 'rank'.$i); + DB::Aowow()->qry('UPDATE ::spell s, dbc_talent t, dbc_talenttab tt SET s.`talentLevel` = (t.`row` * 5) + 10 + (%i * 1) WHERE tt.`id` = t.`tabId` AND tt.`creatureFamilyMask` = 0 AND t.%n = s.`id`', $i - 1, 'rank'.$i); + DB::Aowow()->qry('UPDATE ::spell s, dbc_talent t, dbc_talenttab tt SET s.`talentLevel` = (t.`row` * 12) + 20 + (%i * 4) WHERE tt.`id` = t.`tabId` AND tt.`creatureFamilyMask` <> 0 AND t.%n = s.`id`', $i - 1, 'rank'.$i); } // passive talent - DB::Aowow()->query('UPDATE ?_spell s, dbc_talent t SET s.`cuFlags` = s.`cuFlags` | ?d WHERE t.`talentSpell` = 0 AND (s.`id` = t.`rank1` OR s.`id` = t.`rank2` OR s.`id` = t.`rank3` OR s.`id` = t.`rank4` OR s.`id` = t.`rank5`)', SPELL_CU_TALENT); + DB::Aowow()->qry('UPDATE ::spell s, dbc_talent t SET s.`cuFlags` = s.`cuFlags` | %i WHERE t.`talentSpell` = 0 AND (s.`id` = t.`rank1` OR s.`id` = t.`rank2` OR s.`id` = t.`rank3` OR s.`id` = t.`rank4` OR s.`id` = t.`rank5`)', SPELL_CU_TALENT); // spell taught by talent - DB::Aowow()->query('UPDATE ?_spell s, dbc_talent t SET s.`cuFlags` = s.`cuFlags` | ?d WHERE t.`talentSpell` = 1 AND (s.`id` = t.`rank1` OR s.`id` = t.`rank2` OR s.`id` = t.`rank3` OR s.`id` = t.`rank4` OR s.`id` = t.`rank5`)', SPELL_CU_TALENTSPELL); + DB::Aowow()->qry('UPDATE ::spell s, dbc_talent t SET s.`cuFlags` = s.`cuFlags` | %i WHERE t.`talentSpell` = 1 AND (s.`id` = t.`rank1` OR s.`id` = t.`rank2` OR s.`id` = t.`rank3` OR s.`id` = t.`rank4` OR s.`id` = t.`rank5`)', SPELL_CU_TALENTSPELL); /*********/ @@ -456,17 +456,17 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[spell] - misc fixups & icons'); // FU [FixUps] - DB::Aowow()->query('UPDATE ?_spell SET `reqRaceMask` = ?d WHERE `skillLine1` = ?d', ChrRace::DRAENEI->toMask(), 760); // Draenei Racials - DB::Aowow()->query('UPDATE ?_spell SET `reqRaceMask` = ?d WHERE `skillLine1` = ?d', ChrRace::BLOODELF->toMask(), 756); // Bloodelf Racials - DB::Aowow()->query('UPDATE ?_spell SET `reqClassMask` = ?d WHERE `id` = ?d', ChrClass::MAGE->toMask(), 30449); // Mage - Spellsteal + DB::Aowow()->qry('UPDATE ::spell SET `reqRaceMask` = %i WHERE `skillLine1` = %i', ChrRace::DRAENEI->toMask(), 760); // Draenei Racials + DB::Aowow()->qry('UPDATE ::spell SET `reqRaceMask` = %i WHERE `skillLine1` = %i', ChrRace::BLOODELF->toMask(), 756); // Bloodelf Racials + DB::Aowow()->qry('UPDATE ::spell SET `reqClassMask` = %i WHERE `id` = %i', ChrClass::MAGE->toMask(), 30449); // Mage - Spellsteal // triggered by spell - DB::Aowow()->query( - 'UPDATE ?_spell a - JOIN ( SELECT effect1TriggerSpell as id FROM ?_spell WHERE effect1Id NOT IN (36, 57, 133) AND effect1TriggerSpell <> 0 UNION - SELECT effect2TriggerSpell as id FROM ?_spell WHERE effect2Id NOT IN (36, 57, 133) AND effect2TriggerSpell <> 0 UNION - SELECT effect3TriggerSpell as id FROM ?_spell WHERE effect3Id NOT IN (36, 57, 133) AND effect3TriggerSpell <> 0 ) as b - SET cuFlags = cuFlags | ?d + DB::Aowow()->qry( + 'UPDATE ::spell a + JOIN ( SELECT effect1TriggerSpell as id FROM ::spell WHERE effect1Id NOT IN (36, 57, 133) AND effect1TriggerSpell <> 0 UNION + SELECT effect2TriggerSpell as id FROM ::spell WHERE effect2Id NOT IN (36, 57, 133) AND effect2TriggerSpell <> 0 UNION + SELECT effect3TriggerSpell as id FROM ::spell WHERE effect3Id NOT IN (36, 57, 133) AND effect3TriggerSpell <> 0 ) as b + SET cuFlags = cuFlags | %i WHERE a.id = b.id', SPELL_CU_TRIGGERED); @@ -477,41 +477,41 @@ CLISetup::registerSetup("sql", new class extends SetupScript LEFT JOIN dbc_talent t1 ON t1.rank1 = s.id LEFT JOIN dbc_talent t2 ON t2.rank2 = s.id LEFT JOIN dbc_talent t3 ON t3.rank3 = s.id - WHERE effect1CreateItemId > 0 AND (effect1Id in (?a) OR effect1AuraId in (?a)) AND t1.id IS NULL AND t2.id IS NULL AND t3.id IS NULL + WHERE effect1CreateItemId > 0 AND (effect1Id IN %in OR effect1AuraId IN %in) AND t1.id IS NULL AND t2.id IS NULL AND t3.id IS NULL UNION SELECT s.id AS ARRAY_KEY, effect2CreateItemId FROM dbc_spell s LEFT JOIN dbc_talent t1 ON t1.rank1 = s.id LEFT JOIN dbc_talent t2 ON t2.rank2 = s.id LEFT JOIN dbc_talent t3 ON t3.rank3 = s.id - WHERE effect2CreateItemId > 0 AND (effect2Id in (?a) OR effect2AuraId in (?a)) AND t1.id IS NULL AND t2.id IS NULL AND t3.id IS NULL + WHERE effect2CreateItemId > 0 AND (effect2Id IN %in OR effect2AuraId IN %in) AND t1.id IS NULL AND t2.id IS NULL AND t3.id IS NULL UNION SELECT s.id AS ARRAY_KEY, effect3CreateItemId FROM dbc_spell s LEFT JOIN dbc_talent t1 ON t1.rank1 = s.id LEFT JOIN dbc_talent t2 ON t2.rank2 = s.id LEFT JOIN dbc_talent t3 ON t3.rank3 = s.id - WHERE effect3CreateItemId > 0 AND (effect3Id in (?a) OR effect3AuraId in (?a)) AND t1.id IS NULL AND t2.id IS NULL AND t3.id IS NULL', + WHERE effect3CreateItemId > 0 AND (effect3Id IN %in OR effect3AuraId IN %in) AND t1.id IS NULL AND t2.id IS NULL AND t3.id IS NULL', SpellList::EFFECTS_ITEM_CREATE, SpellList::AURAS_ITEM_CREATE, SpellList::EFFECTS_ITEM_CREATE, SpellList::AURAS_ITEM_CREATE, SpellList::EFFECTS_ITEM_CREATE, SpellList::AURAS_ITEM_CREATE); - $itemInfo = DB::World()->select('SELECT entry AS ARRAY_KEY, displayId AS d, Quality AS q FROM item_template WHERE entry IN (?a)', $itemSpells); + $itemInfo = DB::World()->selectAssoc('SELECT entry AS ARRAY_KEY, displayId AS d, Quality AS q FROM item_template WHERE entry IN %in', $itemSpells); foreach ($itemSpells as $sId => $itemId) if (isset($itemInfo[$itemId])) - DB::Aowow()->query('UPDATE ?_spell s, ?_icons ic, dbc_itemdisplayinfo idi SET s.iconIdAlt = ic.id, s.cuFlags = s.cuFlags | ?d WHERE ic.name_source = LOWER(idi.inventoryIcon1) AND idi.id = ?d AND s.id = ?d', ((7 - $itemInfo[$itemId]['q']) << 8), $itemInfo[$itemId]['d'], $sId); + DB::Aowow()->qry('UPDATE ::spell s, ::icons ic, dbc_itemdisplayinfo idi SET s.iconIdAlt = ic.id, s.cuFlags = s.cuFlags | %i WHERE ic.name_source = LOWER(idi.inventoryIcon1) AND idi.id = %i AND s.id = %i', ((7 - $itemInfo[$itemId]['q']) << 8), $itemInfo[$itemId]['d'], $sId); - $itemReqs = DB::World()->selectCol('SELECT entry AS ARRAY_KEY, requiredSpell FROM item_template WHERE requiredSpell NOT IN (?a)', [0, 34090, 34091]); // not riding + $itemReqs = DB::World()->selectCol('SELECT entry AS ARRAY_KEY, requiredSpell FROM item_template WHERE requiredSpell NOT IN %in', [0, 34090, 34091]); // not riding foreach ($itemReqs AS $itemId => $req) - DB::Aowow()->query('UPDATE ?_spell SET reqSpellId = ?d WHERE skillLine1 IN (?a) AND effect1CreateItemId = ?d', $req, [SKILL_BLACKSMITHING, SKILL_LEATHERWORKING, SKILL_TAILORING, SKILL_ENGINEERING], $itemId); + DB::Aowow()->qry('UPDATE ::spell SET reqSpellId = %i WHERE skillLine1 IN %in AND effect1CreateItemId = %i', $req, [SKILL_BLACKSMITHING, SKILL_LEATHERWORKING, SKILL_TAILORING, SKILL_ENGINEERING], $itemId); // setting icons - DB::Aowow()->query('UPDATE ?_spell s, ?_icons ic, dbc_spellicon si SET s.iconId = ic.id WHERE s.iconIdBak = si.id AND ic.name_source = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1))'); + DB::Aowow()->qry('UPDATE ::spell s, ::icons ic, dbc_spellicon si SET s.`iconId` = ic.`id` WHERE s.`iconIdBak` = si.`id` AND ic.`name_source` = LOWER(SUBSTRING_INDEX(si.`iconPath`, "\\", -1))'); // hide internal stuff from listviews // QA*; *DND*; square brackets anything; *(NYI)*; *(TEST)* // cant catch raw: NYI (uNYIelding); PH (PHasing) - DB::Aowow()->query('UPDATE ?_spell SET cuFlags = cuFlags | ?d WHERE name_loc0 LIKE "QA%" OR name_loc0 LIKE "%DND%" OR name_loc0 LIKE "%[%" OR name_loc0 LIKE "%(NYI)%" OR name_loc0 LIKE "%(TEST)%"', CUSTOM_EXCLUDE_FOR_LISTVIEW); + DB::Aowow()->qry('UPDATE ::spell SET cuFlags = cuFlags | %i WHERE name_loc0 LIKE "QA%" OR name_loc0 LIKE "%DND%" OR name_loc0 LIKE "%[%" OR name_loc0 LIKE "%(NYI)%" OR name_loc0 LIKE "%(TEST)%"', CUSTOM_EXCLUDE_FOR_LISTVIEW); /**************/ @@ -521,10 +521,10 @@ CLISetup::registerSetup("sql", new class extends SetupScript CLI::write('[spell] - applying categories'); // player talents (-2) - DB::Aowow()->query('UPDATE ?_spell s, dbc_talent t SET s.typeCat = -2 WHERE t.tabId NOT IN (409, 410, 411) AND (s.id = t.rank1 OR s.id = t.rank2 OR s.id = t.rank3 OR s.id = t.rank4 OR s.id = t.rank5)'); + DB::Aowow()->qry('UPDATE ::spell s, dbc_talent t SET s.typeCat = -2 WHERE t.tabId NOT IN (409, 410, 411) AND (s.id = t.rank1 OR s.id = t.rank2 OR s.id = t.rank3 OR s.id = t.rank4 OR s.id = t.rank5)'); // pet spells (-3) - DB::Aowow()->query('UPDATE ?_spell s SET s.typeCat = -3 WHERE (s.cuFlags & 0x3) = 0 AND s.skillline1 IN (?a)', + DB::Aowow()->qry('UPDATE ::spell s SET s.typeCat = -3 WHERE (s.cuFlags & 0x3) = 0 AND s.skillline1 IN %in', array_merge( array_column(Game::$skillLineMask[-1], 1), // hunter pets array_column(Game::$skillLineMask[-2], 1), // warlock pets @@ -534,22 +534,22 @@ CLISetup::registerSetup("sql", new class extends SetupScript ); // racials (-4) - DB::Aowow()->query('UPDATE ?_spell s SET s.typeCat = -4 WHERE s.skillLine1 IN (101, 124, 125, 126, 220, 733, 753, 754, 756, 760)'); + DB::Aowow()->qry('UPDATE ::spell s SET s.typeCat = -4 WHERE s.skillLine1 IN (101, 124, 125, 126, 220, 733, 753, 754, 756, 760)'); // mounts (-5) - DB::Aowow()->query('UPDATE ?_spell s SET s.typeCat = -5 WHERE s.effect1AuraId = 78 AND (s.skillLine1 IN (354, 594, 772, 777) OR (s.skillLine1 > 0 AND s.skillLine2OrMask = 777))'); + DB::Aowow()->qry('UPDATE ::spell s SET s.typeCat = -5 WHERE s.effect1AuraId = 78 AND (s.skillLine1 IN (354, 594, 772, 777) OR (s.skillLine1 > 0 AND s.skillLine2OrMask = 777))'); // companions (-6) - DB::Aowow()->query('UPDATE ?_spell s SET s.typeCat = -6 WHERE s.skillLine1 = 778'); + DB::Aowow()->qry('UPDATE ::spell s SET s.typeCat = -6 WHERE s.skillLine1 = 778'); // pet talents (-7) - DB::Aowow()->query('UPDATE ?_spell s, dbc_talent t SET s.typeCat = -7, s.cuFlags = s.cuFlags | 0x10 WHERE t.tabId = 409 AND (s.id = t.rank1 OR s.id = t.rank2 OR s.id = t.rank3)'); - DB::Aowow()->query('UPDATE ?_spell s, dbc_talent t SET s.typeCat = -7, s.cuFlags = s.cuFlags | 0x08 WHERE t.tabId = 410 AND (s.id = t.rank1 OR s.id = t.rank2 OR s.id = t.rank3)'); - DB::Aowow()->query('UPDATE ?_spell s, dbc_talent t SET s.typeCat = -7, s.cuFlags = s.cuFlags | 0x20 WHERE t.tabId = 411 AND (s.id = t.rank1 OR s.id = t.rank2 OR s.id = t.rank3)'); + DB::Aowow()->qry('UPDATE ::spell s, dbc_talent t SET s.typeCat = -7, s.cuFlags = s.cuFlags | 0x10 WHERE t.tabId = 409 AND (s.id = t.rank1 OR s.id = t.rank2 OR s.id = t.rank3)'); + DB::Aowow()->qry('UPDATE ::spell s, dbc_talent t SET s.typeCat = -7, s.cuFlags = s.cuFlags | 0x08 WHERE t.tabId = 410 AND (s.id = t.rank1 OR s.id = t.rank2 OR s.id = t.rank3)'); + DB::Aowow()->qry('UPDATE ::spell s, dbc_talent t SET s.typeCat = -7, s.cuFlags = s.cuFlags | 0x20 WHERE t.tabId = 411 AND (s.id = t.rank1 OR s.id = t.rank2 OR s.id = t.rank3)'); // internal (-9) by faaaaaar not complete - DB::Aowow()->query('UPDATE ?_spell s SET s.typeCat = -9 WHERE s.skillLine1 = 769'); - DB::Aowow()->query('UPDATE ?_spell s SET s.typeCat = -9 WHERE s.typeCat = 0 AND s.cuFlags = 0 AND ( + DB::Aowow()->qry('UPDATE ::spell s SET s.typeCat = -9 WHERE s.skillLine1 = 769'); + DB::Aowow()->qry('UPDATE ::spell s SET s.typeCat = -9 WHERE s.typeCat = 0 AND s.cuFlags = 0 AND ( s.name_loc0 LIKE "%qa%" OR s.name_loc0 LIKE "%debug%" OR s.name_loc0 LIKE "%internal%" OR @@ -559,48 +559,48 @@ CLISetup::registerSetup("sql", new class extends SetupScript ); // proficiencies (-11) - DB::Aowow()->query('UPDATE ?_spell s, dbc_skillline sl SET s.typeCat = -11 WHERE s.skillLine1 = sl.id AND sl.categoryId IN (6, 8, 10)'); + DB::Aowow()->qry('UPDATE ::spell s, dbc_skillline sl SET s.typeCat = -11 WHERE s.skillLine1 = sl.id AND sl.categoryId IN (6, 8, 10)'); // glyphs (-13) - DB::Aowow()->query('UPDATE ?_spell s, dbc_glyphproperties gp SET s.cuFlags = s.cuFlags | IF(gp.typeFlags, ?d, ?d), s.typeCat = -13 WHERE gp.typeFlags IN (0, 1) AND gp.id = s.effect1MiscValue AND s.effect1Id = 74', SPELL_CU_GLYPH_MINOR, SPELL_CU_GLYPH_MAJOR); + DB::Aowow()->qry('UPDATE ::spell s, dbc_glyphproperties gp SET s.cuFlags = s.cuFlags | IF(gp.typeFlags, %i, %i), s.typeCat = -13 WHERE gp.typeFlags IN (0, 1) AND gp.id = s.effect1MiscValue AND s.effect1Id = 74', SPELL_CU_GLYPH_MINOR, SPELL_CU_GLYPH_MAJOR); $glyphs = DB::World()->selectCol('SELECT it.spellid_1 AS ARRAY_KEY, it.AllowableClass FROM item_template it WHERE it.class = 16'); foreach ($glyphs as $spell => $classMask) - DB::Aowow()->query('UPDATE ?_spell s, dbc_glyphproperties gp SET s.reqClassMask = ?d WHERE gp.typeFlags IN (0, 1) AND gp.id = s.effect1MiscValue AND s.effect1Id = 74 AND s.id = ?d', $classMask, $spell); + DB::Aowow()->qry('UPDATE ::spell s, dbc_glyphproperties gp SET s.reqClassMask = %i WHERE gp.typeFlags IN (0, 1) AND gp.id = s.effect1MiscValue AND s.effect1Id = 74 AND s.id = %i', $classMask, $spell); // class Spells (7) - DB::Aowow()->query('UPDATE ?_spell s, dbc_skillline sl SET s.typeCat = 7 WHERE s.typeCat = 0 AND s.skillLine1 = sl.id AND sl.categoryId = 7'); + DB::Aowow()->qry('UPDATE ::spell s, dbc_skillline sl SET s.typeCat = 7 WHERE s.typeCat = 0 AND s.skillLine1 = sl.id AND sl.categoryId = 7'); // hide some internal/unused stuffs - DB::Aowow()->query('UPDATE ?_spell s SET s.cuFlags = ?d WHERE s.typeCat = 7 AND ( + DB::Aowow()->qry('UPDATE ::spell s SET s.cuFlags = %i WHERE s.typeCat = 7 AND ( s.name_loc0 LIKE "%passive%" OR s.name_loc0 LIKE "%effect%" OR s.name_loc0 LIKE "%improved%" OR s.name_loc0 LIKE "%prototype%" OR -- can probably be extended (s.id NOT IN (47241, 59879, 59671) AND s.baseLevel <= 1 AND s.reqclassMask = 0) OR -- can probably still be extended (s.SpellFamilyId = 15 AND s.SpellFamilyFlags1 & 0x2000 AND s.SpellDescriptionVariableId <> 84) OR -- DK: Skill Coil (s.SpellFamilyId = 10 AND s.SpellFamilyFlags2 & 0x1000000 AND s.attributes1 = 0) OR -- Paladin: Bacon of Light hmm.. Bacon.... :] (s.SpellFamilyId = 6 AND s.SpellFamilyFlags3 & 0x4000) OR -- Priest: Lolwell Renew (s.SpellFamilyId = 6 AND s.SpellFamilyFlags1 & 0x8000000 AND s.rank_loc0 <> "") OR -- Priest: Bling Bling - (s.SpellFamilyId = 8 AND s.attributes0 = 0x50 AND s.attributes1 & 0x400) OR -- Rogue: Intuition (dropped Talent..? looks nice though) + (s.SpellFamilyId = 8 AND s.attributes0 = 0x50 AND s.attributes1 & 0x400) OR -- Rogue: Intuition (s.SpellfamilyId = 11 AND s.SpellFamilyFlags1 & 3 AND s.attributes1 = 1024) OR -- Shaman: Lightning Overload procs (s.attributes0 = 0x20000000 AND s.attributes3 = 0x10000000) -- Master Demonologist (FamilyId = 0) )', CUSTOM_EXCLUDE_FOR_LISTVIEW); foreach (ChrClass::cases() as $cl) - DB::Aowow()->query( - 'UPDATE ?_spell s, dbc_skillline sl, dbc_skillraceclassinfo srci + DB::Aowow()->qry( + 'UPDATE ::spell s, dbc_skillline sl, dbc_skillraceclassinfo srci SET s.`reqClassMask` = srci.`classMask` WHERE s.`typeCat` IN (-2, 7) AND (s.`attributes0` & 0x80) = 0 AND s.`skillLine1` = srci.`skillLine` AND sl.`categoryId` = 7 AND - srci.`skillline` <> 769 AND srci.`skillline` = sl.`id` AND srci.`flags` & 0x90 AND srci.`classMask` & ?d', + srci.`skillline` <> 769 AND srci.`skillline` = sl.`id` AND srci.`flags` & 0x90 AND srci.`classMask` & %i', $cl->toMask() ); // secondary Skills (9) - DB::Aowow()->query('UPDATE ?_spell s SET s.typeCat = 9 WHERE s.typeCat = 0 AND (s.skillLine1 IN (?a) OR (s.skillLine1 > 0 AND s.skillLine2OrMask IN (?a)))', SKILLS_TRADE_SECONDARY, SKILLS_TRADE_SECONDARY); + DB::Aowow()->qry('UPDATE ::spell s SET s.typeCat = 9 WHERE s.typeCat = 0 AND (s.skillLine1 IN %in OR (s.skillLine1 > 0 AND s.skillLine2OrMask IN %in))', SKILLS_TRADE_SECONDARY, SKILLS_TRADE_SECONDARY); // primary Skills (11) - DB::Aowow()->query('UPDATE ?_spell s SET s.typeCat = 11 WHERE s.typeCat = 0 AND s.skillLine1 IN (?a)', SKILLS_TRADE_PRIMARY); + DB::Aowow()->qry('UPDATE ::spell s SET s.typeCat = 11 WHERE s.typeCat = 0 AND s.skillLine1 IN %in', SKILLS_TRADE_PRIMARY); // npc spells (-8) (run as last! .. missing from npc_scripts? "enum Spells { \s+(\w\d_)+\s+=\s(\d+) }" and "#define SPELL_(\d\w_)+\s+(\d+)") // RAID_MODE(1, 2[, 3, 4]) - macro still not considered $world = DB::World()->selectCol( - 'SELECT ss.`action_param1` FROM smart_scripts ss WHERE ss.`action_type` IN (?a) UNION + 'SELECT ss.`action_param1` FROM smart_scripts ss WHERE ss.`action_type` IN %in UNION SELECT cts.`Spell` FROM creature_template_spell cts UNION SELECT nscs.`spell_id` FROM npc_spellclick_spells nscs', [SmartAction::ACTION_CAST, SmartAction::ACTION_ADD_AURA, SmartAction::ACTION_SELF_CAST, SmartAction::ACTION_CROSS_CAST] @@ -617,7 +617,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript $world = array_merge($world, array_filter(explode(' ', $a))); } - DB::Aowow()->query('UPDATE ?_spell s SET s.typeCat = -8 WHERE s.typeCat = 0 AND s.id IN (?a)', $world); + DB::Aowow()->qry('UPDATE ::spell s SET s.typeCat = -8 WHERE s.typeCat = 0 AND s.id IN %in', $world); /**********/ @@ -658,14 +658,14 @@ CLISetup::registerSetup("sql", new class extends SetupScript ); $queryIcons = - 'SELECT s.id, s.name_loc0, s.skillLine1 as skill, ic.id as icon, s.typeCat * s.typeCat AS prio - FROM ?_spell s - LEFT JOIN dbc_spellicon si ON s.iconIdBak = si.id - LEFT JOIN ?_icons ic ON ic.name_source = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1)) - WHERE [WHERE] AND (s.cuFlags & ?d) = 0 AND s.typeCat IN (0, 7, -2) -- not triggered; class spells first, talents second, unk last + 'SELECT s.`id`, s.`name_loc0`, s.`skillLine1` AS "skill", ic.`id` AS "icon", s.`typeCat` * s.`typeCat` AS "prio" + FROM ::spell s + LEFT JOIN dbc_spellicon si ON s.`iconIdBak` = si.`id` + LEFT JOIN ::icons ic ON ic.`name_source` = LOWER(SUBSTRING_INDEX(si.`iconPath`, "\\", -1)) + WHERE %and ORDER BY prio DESC'; - $effects = DB::Aowow()->select( + $effects = DB::Aowow()->selectAssoc( 'SELECT s2.id AS ARRAY_KEY, s1.id, s1.name_loc0, @@ -676,9 +676,10 @@ CLISetup::registerSetup("sql", new class extends SetupScript s1.effect1SpellClassMaskB, s1.effect2SpellClassMaskB, s1.effect3SpellClassMaskB, s1.effect1SpellClassMaskC, s1.effect2SpellClassMaskC, s1.effect3SpellClassMaskC FROM dbc_glyphproperties gp - JOIN ?_spell s1 ON s1.id = gp.spellId - JOIN ?_spell s2 ON s2.effect1MiscValue = gp.id AND s2.effect1Id = 74 - WHERE gp.typeFlags IN (0, 1)' // AND s2.id In (58271, 56297, 56289, 63941, 58275) + JOIN ::spell s1 ON s1.id = gp.spellId + JOIN ::spell s2 ON s2.effect1MiscValue = gp.id AND s2.effect1Id = %i + WHERE gp.typeFlags IN (0, 1)', // AND s2.id In (58271, 56297, 56289, 63941, 58275) + SPELL_EFFECT_APPLY_GLYPH ); foreach ($effects as $applyId => $glyphEffect) @@ -690,41 +691,54 @@ CLISetup::registerSetup("sql", new class extends SetupScript // first: manuall replace if ($applyId == 57144) // has no skillLine.. :/ { - DB::Aowow()->query('UPDATE ?_spell s, ?_icons ic SET s.skillLine1 = ?d, s.iconIdAlt = ic.id WHERE s.id = ?d AND ic.name = ?', 253, 57144, 'ability_poisonsting'); + DB::Aowow()->qry('UPDATE ::spell s, ::icons ic SET s.skillLine1 = %i, s.iconIdAlt = ic.id WHERE s.id = %i AND ic.name = %s', 253, 57144, 'ability_poisonsting'); continue; } // second: search by name and family equality if (!$icons) { + $where = array( + ['(s.cuFlags & %i) = 0', SPELL_CU_TRIGGERED], + ['s.typeCat IN (0, 7, -2)'] // not triggered; class spells first, talents second, unk last + ); + $search = !empty($glyphAffects[$applyId]) ? $glyphAffects[$applyId] : str_replace('Glyph of ', '', $glyphEffect['name_loc0']); if (is_int($search)) - $where = "?d AND s.id = ?d"; + $where[] = ['s.`id` = %i', $search]; else - $where = "s.SpellFamilyId = ?d AND s.name_loc0 LIKE ?"; + $where[] = ['s.`SpellFamilyId` = %i AND s.`name_loc0` = %s', $fam, $search]; - $qry = str_replace('[WHERE]', $where, $queryIcons); - $icons = DB::Aowow()->selectRow($qry, $fam ?: 1, $search, SPELL_CU_TRIGGERED); + $icons = DB::Aowow()->selectRow($queryIcons, $where); } // third: match by SpellFamily affect mask while (empty($icons) && $i < 3) { $i++; - $m1 = $glyphEffect['effect'.$i.'SpellClassMaskA']; - $m2 = $glyphEffect['effect'.$i.'SpellClassMaskB']; - $m3 = $glyphEffect['effect'.$i.'SpellClassMaskC']; + $m1 = $glyphEffect['effect'.$i.'SpellClassMaskA']; + $m2 = $glyphEffect['effect'.$i.'SpellClassMaskB']; + $m3 = $glyphEffect['effect'.$i.'SpellClassMaskC']; - if ($glyphEffect['effect'.$i.'Id'] != 6 || (!$m1 && !$m2 && !$m3)) + if ($glyphEffect['effect'.$i.'Id'] != SPELL_EFFECT_APPLY_AURA || (!$m1 && !$m2 && !$m3)) continue; - $where = "s.SpellFamilyId = ?d AND (s.SpellFamilyFlags1 & ?d OR s.SpellFamilyFlags2 & ?d OR s.SpellFamilyFlags3 & ?d)"; + $where = array( + ['(s.`cuFlags` & %i) = 0', SPELL_CU_TRIGGERED], + ['s.`typeCat` IN (0, 7, -2)'], // not triggered; class spells first, talents second, unk last + ['s.`SpellFamilyId` = %i', $fam], + [DB::OR, [ + ['s.`SpellFamilyFlags1` & %i', $m1], + ['s.`SpellFamilyFlags2` & %i', $m2], + ['s.`SpellFamilyFlags3` & %i', $m3] + ]] + ); - $icons = DB::Aowow()->selectRow(str_replace('[WHERE]', $where, $queryIcons), $fam, $m1, $m2, $m3, SPELL_CU_TRIGGERED); + $icons = DB::Aowow()->selectRow($queryIcons, $where); } if ($icons) - DB::Aowow()->query('UPDATE ?_spell s SET s.skillLine1 = ?d, s.iconIdAlt = ?d WHERE s.id = ?d', $icons['skill'], $icons['icon'], $applyId); + DB::Aowow()->qry('UPDATE ::spell s SET s.`skillLine1` = %i, s.`iconIdAlt` = %i WHERE s.`id` = %i', $icons['skill'], $icons['icon'], $applyId); else CLI::write('[spell] '.str_pad('['.$glyphEffect['id'].']', 8).'could not match '.CLI::bold($glyphEffect['name_loc0']).' with affected spells', CLI::LOG_WARN); } diff --git a/setup/tools/sqlgen/spelldifficulty.ss.php b/setup/tools/sqlgen/spelldifficulty.ss.php index a47f4919..987e839e 100644 --- a/setup/tools/sqlgen/spelldifficulty.ss.php +++ b/setup/tools/sqlgen/spelldifficulty.ss.php @@ -19,32 +19,32 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $worldDependency = ['spelldifficulty_dbc']; protected $setupAfter = [['creature', 'spawns'], []]; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE TABLE ?_spelldifficulty'); + DB::Aowow()->qry('TRUNCATE TABLE ::spelldifficulty'); - DB::Aowow()->query('INSERT INTO ?_spelldifficulty SELECT GREATEST(`normal10`, 0), GREATEST(`normal25`, 0), GREATEST(`heroic10`, 0), GREATEST(`heroic25`, 0), IF(`heroic10` > 0, 2, 0) FROM dbc_spelldifficulty'); + DB::Aowow()->qry('INSERT INTO ::spelldifficulty SELECT GREATEST(`normal10`, 0), GREATEST(`normal25`, 0), GREATEST(`heroic10`, 0), GREATEST(`heroic25`, 0), IF(`heroic10` > 0, 2, 0) FROM dbc_spelldifficulty'); - $rows = DB::World()->select('SELECT `spellid0`, `spellid1`, `spellid2`, `spellid3`, IF(`spellid2` > 0, 2, 0) FROM spelldifficulty_dbc'); + $rows = DB::World()->selectAssoc('SELECT `spellid0`, `spellid1`, `spellid2`, `spellid3`, IF(`spellid2` > 0, 2, 0) FROM spelldifficulty_dbc'); foreach ($rows as $r) - DB::Aowow()->query('INSERT INTO ?_spelldifficulty VALUES (?a)', array_values($r)); + DB::Aowow()->qry('INSERT INTO ::spelldifficulty VALUES %l', $r); CLI::write('[spelldifficulty] - trying to assign map type by traversing creature spells > spawns'); // try to update mode of ambiguous entries - $baseSpells = DB::Aowow()->selectCol('SELECT `normal10` FROM ?_spelldifficulty WHERE `heroic10` = 0 AND `heroic25` = 0'); + $baseSpells = DB::Aowow()->selectCol('SELECT `normal10` FROM ::spelldifficulty WHERE `heroic10` = 0 AND `heroic25` = 0'); for ($i = 1; $i < 9; $i++) - DB::Aowow()->query( - 'UPDATE ?_spelldifficulty sd, - (SELECT c.?# AS "spell", BIT_OR(CASE WHEN z.`type` = ?d THEN 1 WHEN z.`type` = ?d THEN 2 WHEN z.`type` = ?d THEN 2 ELSE 0 END) AS "mapType" - FROM ?_creature c - JOIN ?_spawns s ON c.id = s.typeId AND s.type = ?d - JOIN ?_zones z ON z.id = s.areaId - WHERE c.?# IN (?a) - GROUP BY c.?# - HAVING c.?# <> 0) x + DB::Aowow()->qry( + 'UPDATE ::spelldifficulty sd, + (SELECT c.%n AS "spell", BIT_OR(CASE WHEN z.`type` = %i THEN 1 WHEN z.`type` = %i THEN 2 WHEN z.`type` = %i THEN 2 ELSE 0 END) AS "mapType" + FROM ::creature c + JOIN ::spawns s ON c.id = s.typeId AND s.type = %i + JOIN ::zones z ON z.id = s.areaId + WHERE c.%n IN %in + GROUP BY c.%n + HAVING c.%n <> 0) x SET sd.`mapType` = x.`mapType` WHERE sd.`normal10` = x.`spell`', 'spell'.$i, MAP_TYPE_DUNGEON_HC, MAP_TYPE_MMODE_RAID, MAP_TYPE_MMODE_RAID_HC, @@ -62,14 +62,14 @@ CLISetup::registerSetup("sql", new class extends SetupScript foreach ($smartCaster as $type => $spells) foreach ($spells as $spellId => $casterEntries) - DB::Aowow()->query( - 'UPDATE ?_spelldifficulty sd, - (SELECT BIT_OR(CASE WHEN z.`type` = ?d THEN 1 WHEN z.`type` = ?d THEN 2 WHEN z.`type` = ?d THEN 2 ELSE 0 END) AS "mapType" - FROM ?_spawns s - JOIN ?_zones z ON z.id = s.areaId - WHERE s.type = ?d AND s.typeId IN (?a) ) sp + DB::Aowow()->qry( + 'UPDATE ::spelldifficulty sd, + (SELECT BIT_OR(CASE WHEN z.`type` = %i THEN 1 WHEN z.`type` = %i THEN 2 WHEN z.`type` = %i THEN 2 ELSE 0 END) AS "mapType" + FROM ::spawns s + JOIN ::zones z ON z.id = s.areaId + WHERE s.type = %i AND s.typeId IN %in ) sp SET sd.`mapType` = IF(sp.`mapType` > 2, 0, sp.`mapType`) - WHERE sd.`normal10` = ?d', + WHERE sd.`normal10` = %i', MAP_TYPE_DUNGEON_HC, MAP_TYPE_MMODE_RAID, MAP_TYPE_MMODE_RAID_HC, $type, $casterEntries, $spellId diff --git a/setup/tools/sqlgen/talents.ss.php b/setup/tools/sqlgen/talents.ss.php index 6b8cdd23..d325e8fd 100644 --- a/setup/tools/sqlgen/talents.ss.php +++ b/setup/tools/sqlgen/talents.ss.php @@ -17,25 +17,25 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $dbcSourceFiles = ['talent', 'talenttab']; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_talents'); + DB::Aowow()->qry('TRUNCATE ::talents'); // class: 0 => hunter pets for ($i = 1; $i < 6; $i++) - DB::Aowow()->query( - 'INSERT INTO ?_talents + DB::Aowow()->qry( + 'INSERT INTO ::talents SELECT t.id, IF(tt.classMask <> 0, LOG(2, tt.classMask) + 1, 0), tt.creatureFamilyMask, IF(tt.creaturefamilyMask <> 0, LOG(2, tt.creaturefamilyMask), tt.tabNumber), t.row, t.column, - t.rank?d, - ?d + t.rank%i, + %i FROM dbc_talenttab tt JOIN dbc_talent t ON tt.id = t.tabId - WHERE t.rank?d <> 0', + WHERE t.rank%i <> 0', $i, $i, $i ); diff --git a/setup/tools/sqlgen/taxi.ss.php b/setup/tools/sqlgen/taxi.ss.php index 36594047..29558a86 100644 --- a/setup/tools/sqlgen/taxi.ss.php +++ b/setup/tools/sqlgen/taxi.ss.php @@ -19,19 +19,19 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $worldDependency = ['creature', 'creature_template']; protected $setupAfter = [['dungeonmap', 'worldmaparea'], []]; // accessed by WorldPosition::toZonePos - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_taxipath'); - DB::Aowow()->query('TRUNCATE ?_taxinodes'); + DB::Aowow()->qry('TRUNCATE ::taxipath'); + DB::Aowow()->qry('TRUNCATE ::taxinodes'); /*********/ /* paths */ /*********/ - DB::Aowow()->query('INSERT INTO ?_taxipath SELECT tp.id, tp.startNodeId, tp.endNodeId FROM dbc_taxipath tp WHERE tp.startNodeId > 0 AND tp.EndNodeId > 0'); + DB::Aowow()->qry('INSERT INTO ::taxipath SELECT tp.id, tp.startNodeId, tp.endNodeId FROM dbc_taxipath tp WHERE tp.startNodeId > 0 AND tp.EndNodeId > 0'); // paths are monodirectional and thus exist twice for regular flight travel (which is bidirectional) - $paths = DB::Aowow()->select('SELECT id AS ARRAY_KEY, tp.* FROM ?_taxipath tp'); + $paths = DB::Aowow()->selectAssoc('SELECT id AS ARRAY_KEY, tp.* FROM ::taxipath tp'); foreach ($paths as $i => $p) { foreach ($paths as $j => $_) @@ -39,7 +39,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript if ($_['startNodeId'] != $p['endNodeId'] || $_['endNodeId'] != $p['startNodeId']) continue; - DB::Aowow()->query('DELETE FROM ?_taxipath WHERE id = ?d', $j); + DB::Aowow()->qry('DELETE FROM ::taxipath WHERE id = %i', $j); unset($paths[$j]); unset($paths[$i]); break; @@ -52,7 +52,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript /*********/ // all sensible nodes - $fNodes = DB::Aowow()->select( + $fNodes = DB::Aowow()->selectAssoc( 'SELECT tn.`id`, tn.`mapId`, 100 - ROUND((tn.`posY` - wma.`right`) * 100 / (wma.`left` - wma.`right`), 1) AS "mapX", @@ -92,17 +92,18 @@ CLISetup::registerSetup("sql", new class extends SetupScript ); // all available flightmaster - $fMaster = DB::World()->select('SELECT ct.`entry`, ct.`faction`, c.`map`, c.`position_x` AS "posX", c.`position_y` AS "posY" FROM creature_template ct JOIN creature c ON c.`id` = ct.`entry` WHERE ct.`npcflag` & ?d OR c.`npcflag` & ?d', + $fMaster = DB::World()->selectAssoc( + 'SELECT ct.`entry`, ct.`faction`, c.`map`, c.`position_x` AS "posX", c.`position_y` AS "posY" FROM creature_template ct JOIN creature c ON c.`id` = ct.`entry` WHERE ct.`npcflag` & %i OR c.`npcflag` & %i', NPC_FLAG_FLIGHT_MASTER, NPC_FLAG_FLIGHT_MASTER ); // fetch reactions per faction - $factions = DB::Aowow()->query( + $factions = DB::Aowow()->selectAssoc( 'SELECT `id` AS ARRAY_KEY, IF(`enemyFactionId1` = 1 OR `enemyFactionId2` = 1 OR `enemyFactionId3` = 1 OR `enemyFactionId4` = 1 OR `hostileMask` & 0x3, -1, 1) AS "reactA", IF(`enemyFactionId1` = 2 OR `enemyFactionId2` = 2 OR `enemyFactionId3` = 2 OR `enemyFactionId4` = 2 OR `hostileMask` & 0x5, -1, 1) AS "reactH" FROM dbc_factiontemplate - WHERE `id` IN (?a)', + WHERE `id` IN %in', array_column($fMaster, 'faction')); foreach ($fNodes as $n) @@ -125,8 +126,8 @@ CLISetup::registerSetup("sql", new class extends SetupScript { $n['_dist'] = $dist; $n['typeId'] = $c['entry']; - $n['reactA'] = $factions[$c['faction']]['reactA'] ?? null; - $n['reactH'] = $factions[$c['faction']]['reactH'] ?? null; + $n['reactA'] = $factions[$c['faction']]['reactA'] ?? 0; + $n['reactH'] = $factions[$c['faction']]['reactH'] ?? 0; } } } @@ -141,7 +142,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript unset($n['_mapId'], $n['_posX'], $n['_posY'], $n['_dist'], $n['_scripted']); - DB::Aowow()->query('INSERT INTO ?_taxinodes VALUES (?a)', array_values($n)); + DB::Aowow()->qry('INSERT INTO ::taxinodes VALUES %l', $n); } return true; diff --git a/setup/tools/sqlgen/titles.ss.php b/setup/tools/sqlgen/titles.ss.php index 76b68ae0..94d7dfb1 100644 --- a/setup/tools/sqlgen/titles.ss.php +++ b/setup/tools/sqlgen/titles.ss.php @@ -34,7 +34,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript 168 => 404 ); - public function generate(array $ids = []) : bool + public function generate() : bool { $questQuery = 'SELECT qt.`RewardTitle` AS ARRAY_KEY, qt.`AllowableRaces`, IFNULL(ge.`eventEntry`, 0) AS `eventEntry` @@ -43,38 +43,38 @@ CLISetup::registerSetup("sql", new class extends SetupScript LEFT JOIN game_event ge ON ge.`eventEntry` = sq.`eventEntry` WHERE qt.`RewardTitle` <> 0'; - DB::Aowow()->query('TRUNCATE ?_titles'); - DB::Aowow()->query('INSERT INTO ?_titles SELECT `id`, 0, 0, 0, 0, 0, 0, 0, `bitIdx`, `male_loc0`, `male_loc2`, `male_loc3`, `male_loc4`, `male_loc6`, `male_loc8`, `female_loc0`, `female_loc2`, `female_loc3`, `female_loc4`, `female_loc6`, `female_loc8` FROM dbc_chartitles'); + DB::Aowow()->qry('TRUNCATE ::titles'); + DB::Aowow()->qry('INSERT INTO ::titles SELECT `id`, 0, 0, 0, 0, 0, 0, 0, `bitIdx`, `male_loc0`, `male_loc2`, `male_loc3`, `male_loc4`, `male_loc6`, `male_loc8`, `female_loc0`, `female_loc2`, `female_loc3`, `female_loc4`, `female_loc6`, `female_loc8` FROM dbc_chartitles'); // hide unused titles - DB::Aowow()->query('UPDATE ?_titles SET `cuFlags` = ?d WHERE `id` BETWEEN 85 AND 123 AND `id` NOT IN (113, 120, 121, 122)', CUSTOM_EXCLUDE_FOR_LISTVIEW); + DB::Aowow()->qry('UPDATE ::titles SET `cuFlags` = %i WHERE `id` BETWEEN 85 AND 123 AND `id` NOT IN (113, 120, 121, 122)', CUSTOM_EXCLUDE_FOR_LISTVIEW); // set expansion - DB::Aowow()->query('UPDATE ?_titles SET `expansion` = 2 WHERE `id` >= 72 AND `id` <> 80'); - DB::Aowow()->query('UPDATE ?_titles SET `expansion` = 1 WHERE `id` >= 42 AND `id` <> 46 AND `expansion` = 0'); + DB::Aowow()->qry('UPDATE ::titles SET `expansion` = 2 WHERE `id` >= 72 AND `id` <> 80'); + DB::Aowow()->qry('UPDATE ::titles SET `expansion` = 1 WHERE `id` >= 42 AND `id` <> 46 AND `expansion` = 0'); // set category - DB::Aowow()->query('UPDATE ?_titles SET `category` = 1 WHERE `id` <= 28 OR `id` IN (42, 43, 44, 45, 47, 48, 62, 71, 72, 80, 82, 126, 127, 128, 157, 163, 167, 169, 177)'); - DB::Aowow()->query('UPDATE ?_titles SET `category` = 5 WHERE `id` BETWEEN 96 AND 109 OR `id` IN (83, 84)'); - DB::Aowow()->query('UPDATE ?_titles SET `category` = 2 WHERE `id` BETWEEN 144 AND 156 OR `id` IN (63, 77, 79, 113, 123, 130, 131, 132, 176)'); - DB::Aowow()->query('UPDATE ?_titles SET `category` = 6 WHERE `id` IN (46, 74, 75, 76, 124, 133, 134, 135, 137, 138, 155, 168)'); - DB::Aowow()->query('UPDATE ?_titles SET `category` = 4 WHERE `id` IN (81, 125)'); - DB::Aowow()->query('UPDATE ?_titles SET `category` = 3 WHERE `id` IN (53, 64, 120, 121, 122, 129, 139, 140, 141, 142) OR (`id` >= 158 AND `category` = 0)'); + DB::Aowow()->qry('UPDATE ::titles SET `category` = 1 WHERE `id` <= 28 OR `id` IN (42, 43, 44, 45, 47, 48, 62, 71, 72, 80, 82, 126, 127, 128, 157, 163, 167, 169, 177)'); + DB::Aowow()->qry('UPDATE ::titles SET `category` = 5 WHERE `id` BETWEEN 96 AND 109 OR `id` IN (83, 84)'); + DB::Aowow()->qry('UPDATE ::titles SET `category` = 2 WHERE `id` BETWEEN 144 AND 156 OR `id` IN (63, 77, 79, 113, 123, 130, 131, 132, 176)'); + DB::Aowow()->qry('UPDATE ::titles SET `category` = 6 WHERE `id` IN (46, 74, 75, 76, 124, 133, 134, 135, 137, 138, 155, 168)'); + DB::Aowow()->qry('UPDATE ::titles SET `category` = 4 WHERE `id` IN (81, 125)'); + DB::Aowow()->qry('UPDATE ::titles SET `category` = 3 WHERE `id` IN (53, 64, 120, 121, 122, 129, 139, 140, 141, 142) OR (`id` >= 158 AND `category` = 0)'); // update event - if ($assoc = DB::World()->selectCol('SELECT `holiday` AS ARRAY_KEY, `eventEntry` FROM game_event WHERE `holiday` IN (?a)', array_values($this->titleHoliday))) + if ($assoc = DB::World()->selectCol('SELECT `holiday` AS ARRAY_KEY, `eventEntry` FROM game_event WHERE `holiday` IN %in', array_values($this->titleHoliday))) foreach ($this->titleHoliday as $tId => $hId) if (!empty($assoc[$hId])) - DB::Aowow()->query('UPDATE ?_titles SET `eventId` = ?d WHERE `id` = ?d', $assoc[$hId], $tId); + DB::Aowow()->qry('UPDATE ::titles SET `eventId` = %i WHERE `id` = %i', $assoc[$hId], $tId); // update side - $questInfo = DB::World()->select($questQuery); - $sideUpd = DB::World()->selectCol('SELECT IF(`TitleA`, `TitleA`, `TitleH`) AS ARRAY_KEY, BIT_OR(IF(`TitleA`, ?d, ?d)) AS `side` FROM achievement_reward WHERE (`TitleA` <> 0 AND `TitleH` = 0) OR (`TitleH` <> 0 AND `TitleA` = 0) GROUP BY ARRAY_KEY HAVING `side` <> ?d', + $questInfo = DB::World()->selectAssoc($questQuery); + $sideUpd = DB::World()->selectCol('SELECT IF(`TitleA`, `TitleA`, `TitleH`) AS ARRAY_KEY, BIT_OR(IF(`TitleA`, %i, %i)) AS `side` FROM achievement_reward WHERE (`TitleA` <> 0 AND `TitleH` = 0) OR (`TitleH` <> 0 AND `TitleA` = 0) GROUP BY ARRAY_KEY HAVING `side` <> %i', SIDE_ALLIANCE, SIDE_HORDE, SIDE_BOTH); foreach ($questInfo as $tId => $data) { if ($data['eventEntry']) - DB::Aowow()->query('UPDATE ?_titles SET `eventId` = ?d WHERE `id` = ?d', $data['eventEntry'], $tId); + DB::Aowow()->qry('UPDATE ::titles SET `eventId` = %i WHERE `id` = %i', $data['eventEntry'], $tId); $side = ChrRace::sideFromMask($data['AllowableRaces']); if ($side == SIDE_BOTH) @@ -87,11 +87,11 @@ CLISetup::registerSetup("sql", new class extends SetupScript } foreach ($sideUpd as $tId => $side) if ($side != SIDE_BOTH) - DB::Aowow()->query("UPDATE ?_titles SET `side` = ?d WHERE `id` = ?d", $side, $tId); + DB::Aowow()->qry("UPDATE ::titles SET `side` = %i WHERE `id` = %i", $side, $tId); // update side - sourceless titles (maintain query order) - DB::Aowow()->query('UPDATE ?_titles SET `side` = ?d WHERE `id` <= 28 OR `id` IN (118, 119, 116, 117, 110, 127)', SIDE_HORDE); - DB::Aowow()->query('UPDATE ?_titles SET `side` = ?d WHERE `id` <= 14 OR `id` IN (111, 115, 112, 114, 126)', SIDE_ALLIANCE); + DB::Aowow()->qry('UPDATE ::titles SET `side` = %i WHERE `id` <= 28 OR `id` IN (118, 119, 116, 117, 110, 127)', SIDE_HORDE); + DB::Aowow()->qry('UPDATE ::titles SET `side` = %i WHERE `id` <= 14 OR `id` IN (111, 115, 112, 114, 126)', SIDE_ALLIANCE); $this->reapplyCCFlags('titles', Type::TITLE); diff --git a/setup/tools/sqlgen/zones.ss.php b/setup/tools/sqlgen/zones.ss.php index 08cff871..326c31fe 100644 --- a/setup/tools/sqlgen/zones.ss.php +++ b/setup/tools/sqlgen/zones.ss.php @@ -26,18 +26,18 @@ CLISetup::registerSetup("sql", new class extends SetupScript protected $worldDependency = ['access_requirement', 'areatrigger_teleport']; protected $setupAfter = [['dungeonmap', 'worldmaparea'], []]; - public function generate(array $ids = []) : bool + public function generate() : bool { - DB::Aowow()->query('TRUNCATE ?_zones'); + DB::Aowow()->qry('TRUNCATE ::zones'); - $baseData = DB::Aowow()->query( + $baseData = DB::Aowow()->selectAssoc( 'SELECT a.id, IFNULL(wmt.targetMapId, m.id) AS map, m.id AS mapBak, a.areaTable AS parentArea, IFNULL(wmt.targetMapId, IF(m.areaType = 1, 2, IF(m.areaType = 2, 3, IF(m.areaType = 4, 9, IF(m.isBG = 1, 6, IF(m.id = 571, 10, IF(m.id = 530, 8, m.id))))))) AS category, a.flags, - IF(a.mapId IN (13, 25, 37, 42, 169) OR (a.mapId IN (0, 1, 530, 571) AND wma.id IS NULL) OR a.areaTable <> 0 OR (a.soundAmbience = 0 AND a.mapId IN (0, 1, 530, 571)), ?d, 0) AS cuFlags, + IF(a.mapId IN (13, 25, 37, 42, 169) OR (a.mapId IN (0, 1, 530, 571) AND wma.id IS NULL) OR a.areaTable <> 0 OR (a.soundAmbience = 0 AND a.mapId IN (0, 1, 530, 571)), %i, 0) AS cuFlags, IF(a.flags & 0x01000000, 5, IF(m.isBG = 1, 4, IF(m.areaType = 4, 4, IF(a.flags & 0x00000800, 3, IF(a.factionGroupMask = 6, 2, IF(a.factionGroupMask > 0, LOG2(a.factionGroupMask) - 1, 2)))))) AS faction, -- g_zone_territories m.expansion, IF(m.areaType = 0, 0, IF(m.isBG = 1, 4, IF(m.areaType = 4, 6, IF(md.modeMask & 0xC, 8, IF(md.minPl = 10 AND md.maxPL = 25, 7, IF(m.areaType = 2, 3, IF(m.areaType = 1 AND md.modeMask & 0x2, 5, 2))))))) AS `type`, -- g_zone_instancetypes @@ -48,7 +48,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript IFNULL(lfgIni.levelLFG, 0) AS `levelReqLFG`, 0 AS `levelHeroic`, IF(a.flags & 0x8, 1, IFNULL(bm.minLevel, IFNULL(lfgIni.levelMin, IFNULL(lfgOpen.levelMin, 0)))) AS `levelMin`, - IF(a.flags & 0x8, ?d, IFNULL(bm.maxLevel, IFNULL(lfgIni.levelMax, IFNULL(lfgOpen.levelMax, 0)))) AS `levelMax`, + IF(a.flags & 0x8, %i, IFNULL(bm.maxLevel, IFNULL(lfgIni.levelMax, IFNULL(lfgOpen.levelMax, 0)))) AS `levelMax`, "" AS `attunementsN`, "" AS `attunementsH`, GREATEST(m.parentMapId, 0), @@ -79,20 +79,21 @@ CLISetup::registerSetup("sql", new class extends SetupScript CUSTOM_EXCLUDE_FOR_LISTVIEW, MAX_LEVEL ); - DB::Aowow()->query('INSERT INTO ?_zones VALUES (?a)', $baseData); + foreach ($baseData as $bd) + DB::Aowow()->qry('INSERT INTO ::zones VALUES %l', $bd); // set missing graveyards from areatrigger data (auto-resurrect map or just plain errors) // grouped because naxxramas _just has_ to be special with 4 entrances... if ($missingMaps = DB::Aowow()->selectCol('SELECT `id` FROM dbc_map WHERE `parentX` = 0 AND `parentY` = 0 AND `parentMapId` > -1 AND `areaType` NOT IN (0, 3, 4)')) - if ($triggerIds = DB::World()->selectCol('SELECT `target_map`, `id` AS ARRAY_KEY FROM areatrigger_teleport WHERE `target_map` IN (?a) GROUP BY `target_map`', $missingMaps)) - if ($positions = DB::Aowow()->select('SELECT `id` AS `ARRAY_KEY`, `mapId` AS "parentMapId", `posX` AS "parentX", `posY` AS "parentY" FROM dbc_areatrigger WHERE `id` IN (?a)', array_keys($triggerIds))) + if ($triggerIds = DB::World()->selectCol('SELECT `target_map`, `id` AS ARRAY_KEY FROM areatrigger_teleport WHERE `target_map` IN %in GROUP BY `target_map`', $missingMaps)) + if ($positions = DB::Aowow()->selectAssoc('SELECT `id` AS `ARRAY_KEY`, `mapId` AS "parentMapId", `posX` AS "parentX", `posY` AS "parentY" FROM dbc_areatrigger WHERE `id` IN %in', array_keys($triggerIds))) foreach ($positions as $atId => $parentPos) - DB::Aowow()->query('UPDATE ?_zones SET ?a WHERE `mapId` = ?d', $parentPos, $triggerIds[$atId]); + DB::Aowow()->qry('UPDATE ::zones SET %a WHERE `mapId` = %i', $parentPos, $triggerIds[$atId]); // get requirements from world.access_requirement - $zoneReq = DB::World()->select( + $zoneReq = DB::World()->selectAssoc( 'SELECT mapId AS ARRAY_KEY, MIN(level_min) AS reqLevel, MAX(IF(difficulty > 0, level_min, 0)) AS heroicLevel, @@ -108,7 +109,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript GROUP BY mapId' ); - $heroics = DB::Aowow()->selectCol('SELECT DISTINCT mapId FROM ?_zones WHERE type IN (5, 8)'); + $heroics = DB::Aowow()->selectCol('SELECT DISTINCT mapId FROM ::zones WHERE type IN (5, 8)'); foreach ($zoneReq as $mapId => $req) { @@ -167,7 +168,7 @@ CLISetup::registerSetup("sql", new class extends SetupScript $update['attunementsH'] = implode(' ', $aH); } - DB::Aowow()->query('UPDATE ?_zones SET ?a WHERE mapId = ?d', $update, $mapId); + DB::Aowow()->qry('UPDATE ::zones SET %a WHERE mapId = %i', $update, $mapId); } $this->reapplyCCFlags('zones', Type::ZONE);