SharedQueryBuilderTest.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2024 Robin Appelman <robin@icewind.nl>
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace Test\DB\QueryBuilder\Sharded;
  8. use OC\DB\QueryBuilder\Sharded\AutoIncrementHandler;
  9. use OC\DB\QueryBuilder\Sharded\InvalidShardedQueryException;
  10. use OC\DB\QueryBuilder\Sharded\RoundRobinShardMapper;
  11. use OC\DB\QueryBuilder\Sharded\ShardConnectionManager;
  12. use OC\DB\QueryBuilder\Sharded\ShardDefinition;
  13. use OC\DB\QueryBuilder\Sharded\ShardedQueryBuilder;
  14. use OCP\DB\QueryBuilder\IQueryBuilder;
  15. use OCP\IDBConnection;
  16. use OCP\Server;
  17. use Test\TestCase;
  18. /**
  19. * @group DB
  20. */
  21. class SharedQueryBuilderTest extends TestCase {
  22. private IDBConnection $connection;
  23. private AutoIncrementHandler $autoIncrementHandler;
  24. protected function setUp(): void {
  25. if (PHP_INT_SIZE < 8) {
  26. $this->markTestSkipped('Test requires 64bit');
  27. }
  28. $this->connection = Server::get(IDBConnection::class);
  29. $this->autoIncrementHandler = Server::get(AutoIncrementHandler::class);
  30. }
  31. private function getQueryBuilder(string $table, string $shardColumn, string $primaryColumn, array $companionTables = []): ShardedQueryBuilder {
  32. return new ShardedQueryBuilder(
  33. $this->connection->getQueryBuilder(),
  34. [
  35. new ShardDefinition($table, $primaryColumn, [], $shardColumn, new RoundRobinShardMapper(), $companionTables, []),
  36. ],
  37. $this->createMock(ShardConnectionManager::class),
  38. $this->autoIncrementHandler,
  39. );
  40. }
  41. public function testGetShardKeySingleParam(): void {
  42. $query = $this->getQueryBuilder('filecache', 'storage', 'fileid');
  43. $query->select('fileid', 'path')
  44. ->from('filecache')
  45. ->where($query->expr()->eq('storage', $query->createNamedParameter(10, IQueryBuilder::PARAM_INT)));
  46. $this->assertEquals([], $query->getPrimaryKeys());
  47. $this->assertEquals([10], $query->getShardKeys());
  48. }
  49. public function testGetPrimaryKeyParam(): void {
  50. $query = $this->getQueryBuilder('filecache', 'storage', 'fileid');
  51. $query->select('fileid', 'path')
  52. ->from('filecache')
  53. ->where($query->expr()->in('fileid', $query->createNamedParameter([10, 11], IQueryBuilder::PARAM_INT)));
  54. $this->assertEquals([10, 11], $query->getPrimaryKeys());
  55. $this->assertEquals([], $query->getShardKeys());
  56. }
  57. public function testValidateWithShardKey(): void {
  58. $query = $this->getQueryBuilder('filecache', 'storage', 'fileid');
  59. $query->select('fileid', 'path')
  60. ->from('filecache')
  61. ->where($query->expr()->eq('storage', $query->createNamedParameter(10)));
  62. $query->validate();
  63. $this->assertTrue(true);
  64. }
  65. public function testValidateWithPrimaryKey(): void {
  66. $query = $this->getQueryBuilder('filecache', 'storage', 'fileid');
  67. $query->select('fileid', 'path')
  68. ->from('filecache')
  69. ->where($query->expr()->in('fileid', $query->createNamedParameter([10, 11], IQueryBuilder::PARAM_INT)));
  70. $query->validate();
  71. $this->assertTrue(true);
  72. }
  73. public function testValidateWithNoKey(): void {
  74. $query = $this->getQueryBuilder('filecache', 'storage', 'fileid');
  75. $query->select('fileid', 'path')
  76. ->from('filecache')
  77. ->where($query->expr()->lt('size', $query->createNamedParameter(0)));
  78. $this->expectException(InvalidShardedQueryException::class);
  79. $query->validate();
  80. $this->fail('exception expected');
  81. }
  82. public function testValidateNonSharedTable(): void {
  83. $query = $this->getQueryBuilder('filecache', 'storage', 'fileid');
  84. $query->select('configvalue')
  85. ->from('appconfig')
  86. ->where($query->expr()->eq('configkey', $query->createNamedParameter('test')));
  87. $query->validate();
  88. $this->assertTrue(true);
  89. }
  90. public function testGetShardKeyMultipleSingleParam(): void {
  91. $query = $this->getQueryBuilder('filecache', 'storage', 'fileid');
  92. $query->select('fileid', 'path')
  93. ->from('filecache')
  94. ->where($query->expr()->andX(
  95. $query->expr()->gt('mtime', $query->createNamedParameter(0), IQueryBuilder::PARAM_INT),
  96. $query->expr()->orX(
  97. $query->expr()->eq('storage', $query->createNamedParameter(10, IQueryBuilder::PARAM_INT)),
  98. $query->expr()->andX(
  99. $query->expr()->eq('storage', $query->createNamedParameter(11, IQueryBuilder::PARAM_INT)),
  100. $query->expr()->like('path', $query->createNamedParameter('foo/%'))
  101. )
  102. )
  103. ));
  104. $this->assertEquals([], $query->getPrimaryKeys());
  105. $this->assertEquals([10, 11], $query->getShardKeys());
  106. }
  107. }