From 0c48f4d7035ee6babed199a10855a34ba0415fea Mon Sep 17 00:00:00 2001 From: romanetar Date: Thu, 22 Oct 2026 16:42:41 +0200 Subject: [PATCH 1/2] fix(summit-order): add indexes for owner email, hash and payment gateway cart id lookups --- .../model/Version20261022120000.php | 61 ++++++++++++++ ...ctrineSummitOrderRepositoryIndexesTest.php | 82 +++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 database/migrations/model/Version20261022120000.php create mode 100644 tests/DoctrineSummitOrderRepositoryIndexesTest.php diff --git a/database/migrations/model/Version20261022120000.php b/database/migrations/model/Version20261022120000.php new file mode 100644 index 000000000..5858f8854 --- /dev/null +++ b/database/migrations/model/Version20261022120000.php @@ -0,0 +1,61 @@ + '`OwnerEmail`, `OwnerID`', + 'IDX_SummitOrder_Hash' => '`Hash`', + 'IDX_SummitOrder_PaymentGatewayCartId' => '`PaymentGatewayCartId`', + ]; + + /** + * @param Schema $schema + */ + public function up(Schema $schema): void + { + $db = DB::connection("model")->getDatabaseName(); + foreach (self::Indexes as $name => $columns) { + if (!DBHelpers::existsIDX($db, 'SummitOrder', $name)) { + $this->addSql("ALTER TABLE `SummitOrder` ADD INDEX `{$name}` ({$columns}) USING BTREE, ALGORITHM=INPLACE, LOCK=NONE;"); + } + } + } + + public function down(Schema $schema): void + { + $db = DB::connection("model")->getDatabaseName(); + foreach (self::Indexes as $name => $columns) { + if (DBHelpers::existsIDX($db, 'SummitOrder', $name)) { + $this->addSql("ALTER TABLE `SummitOrder` DROP INDEX `{$name}`;"); + } + } + } +} diff --git a/tests/DoctrineSummitOrderRepositoryIndexesTest.php b/tests/DoctrineSummitOrderRepositoryIndexesTest.php new file mode 100644 index 000000000..982470ea4 --- /dev/null +++ b/tests/DoctrineSummitOrderRepositoryIndexesTest.php @@ -0,0 +1,82 @@ +getConnection(); + } + + private function indexColumns(string $index): array + { + $rows = $this->connection()->fetchAllAssociative( + "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.STATISTICS + WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'SummitOrder' AND INDEX_NAME = ? + ORDER BY SEQ_IN_INDEX", + [$index] + ); + return array_column($rows, 'COLUMN_NAME'); + } + + private function explainPossibleKeys(string $sql, array $params): string + { + $rows = $this->connection()->fetchAllAssociative("EXPLAIN " . $sql, $params); + return (string)($rows[0]['possible_keys'] ?? ''); + } + + public function testOwnerEmailOwnerIndexExists(): void + { + $this->assertSame(['OwnerEmail', 'OwnerID'], $this->indexColumns('IDX_SummitOrder_OwnerEmail_Owner')); + } + + public function testHashIndexExists(): void + { + $this->assertSame(['Hash'], $this->indexColumns('IDX_SummitOrder_Hash')); + } + + public function testPaymentGatewayCartIdIndexExists(): void + { + $this->assertSame(['PaymentGatewayCartId'], $this->indexColumns('IDX_SummitOrder_PaymentGatewayCartId')); + } + + public function testAssociationLookupCanUseOwnerEmailOwnerIndex(): void + { + $keys = $this->explainPossibleKeys( + "SELECT ID FROM SummitOrder WHERE OwnerEmail = ? AND OwnerID IS NULL", ['a@b.com']); + $this->assertStringContainsString('IDX_SummitOrder_OwnerEmail_Owner', $keys); + } + + public function testHashLookupCanUseHashIndex(): void + { + $keys = $this->explainPossibleKeys("SELECT ID FROM SummitOrder WHERE Hash = ?", ['x']); + $this->assertStringContainsString('IDX_SummitOrder_Hash', $keys); + } + + public function testCartIdLookupCanUseCartIdIndex(): void + { + $keys = $this->explainPossibleKeys("SELECT ID FROM SummitOrder WHERE PaymentGatewayCartId = ?", ['x']); + $this->assertStringContainsString('IDX_SummitOrder_PaymentGatewayCartId', $keys); + } +} From a4ccaa84e057db30b1ff925e8b8cc330d7895b59 Mon Sep 17 00:00:00 2001 From: romanetar Date: Thu, 22 Oct 2026 16:42:51 +0200 Subject: [PATCH 2/2] refactor(summit-order): remove unused getAllByOwnerEmail and getByExternalIdLockExclusive --- .../Repositories/ISummitOrderRepository.php | 12 ------ .../Summit/DoctrineSummitOrderRepository.php | 38 ------------------- 2 files changed, 50 deletions(-) diff --git a/app/Models/Foundation/Summit/Repositories/ISummitOrderRepository.php b/app/Models/Foundation/Summit/Repositories/ISummitOrderRepository.php index 6c220b838..5a6c20410 100644 --- a/app/Models/Foundation/Summit/Repositories/ISummitOrderRepository.php +++ b/app/Models/Foundation/Summit/Repositories/ISummitOrderRepository.php @@ -35,12 +35,6 @@ public function getByHashLockExclusive(string $hash): ?SummitOrder; */ public function getByPaymentGatewayCartIdExclusiveLock(string $payment_gateway_cart_id): ?SummitOrder; - /** - * @param string $externalId - * @return SummitOrder|null - */ - public function getByExternalIdLockExclusive(string $externalId):?SummitOrder; - /** * @param Summit $summit * @param string $externalId @@ -48,12 +42,6 @@ public function getByExternalIdLockExclusive(string $externalId):?SummitOrder; */ public function getByExternalIdAndSummitLockExclusive(Summit $summit, string $externalId):?SummitOrder; - /** - * @param string $email - * @return mixed - */ - public function getAllByOwnerEmail(string $email); - /** * @param string $email * @return mixed diff --git a/app/Repositories/Summit/DoctrineSummitOrderRepository.php b/app/Repositories/Summit/DoctrineSummitOrderRepository.php index 317bbe5cd..9bf67cd96 100644 --- a/app/Repositories/Summit/DoctrineSummitOrderRepository.php +++ b/app/Repositories/Summit/DoctrineSummitOrderRepository.php @@ -89,25 +89,6 @@ public function getByPaymentGatewayCartIdExclusiveLock(string $payment_gateway_c ->getOneOrNullResult(); } - /** - * @param string $email - * @return mixed - */ - public function getAllByOwnerEmail(string $email) - { - $query = $this->getEntityManager() - ->createQueryBuilder() - ->select("e") - ->from($this->getBaseEntity(), "e") - ->where("e.owner_email = :owner_email"); - - $query->setParameter("owner_email", trim($email)); - return $query->getQuery() - ->setLockMode(\Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE) - ->setHint(\Doctrine\ORM\Query::HINT_REFRESH, true) - ->getResult(); - } - /** * @param string $email * @return mixed @@ -174,25 +155,6 @@ public function getAllConfirmedOlderThanXMinutes(int $minutes, int $max = 100) } - /** - * @param string $externalId - * @return SummitOrder|null - */ - public function getByExternalIdLockExclusive(string $externalId): ?SummitOrder - { - $query = $this->getEntityManager() - ->createQueryBuilder() - ->select("e") - ->from($this->getBaseEntity(), "e") - ->where("e.external_id = :external_id"); - - $query->setParameter("external_id", $externalId); - return $query->getQuery() - ->setLockMode(\Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE) - ->setHint(\Doctrine\ORM\Query::HINT_REFRESH, true) - ->getOneOrNullResult(); - } - /** * @param Summit $summit * @param string $externalId