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 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); + } +}