PoolingShardManager.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php
  2. /*
  3. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. *
  15. * This software consists of voluntary contributions made by many individuals
  16. * and is licensed under the MIT license. For more information, see
  17. * <http://www.doctrine-project.org>.
  18. */
  19. namespace Doctrine\DBAL\Sharding;
  20. /**
  21. * Shard Manager for the Connection Pooling Shard Strategy
  22. *
  23. * @author Benjamin Eberlei <kontakt@beberlei.de>
  24. */
  25. class PoolingShardManager implements ShardManager
  26. {
  27. /**
  28. * @var \Doctrine\DBAL\Sharding\PoolingShardConnection
  29. */
  30. private $conn;
  31. /**
  32. * @var \Doctrine\DBAL\Sharding\ShardChoser\ShardChoser
  33. */
  34. private $choser;
  35. /**
  36. * @var string|null
  37. */
  38. private $currentDistributionValue;
  39. /**
  40. * @param \Doctrine\DBAL\Sharding\PoolingShardConnection $conn
  41. */
  42. public function __construct(PoolingShardConnection $conn)
  43. {
  44. $params = $conn->getParams();
  45. $this->conn = $conn;
  46. $this->choser = $params['shardChoser'];
  47. }
  48. /**
  49. * @return void
  50. */
  51. public function selectGlobal()
  52. {
  53. $this->conn->connect(0);
  54. $this->currentDistributionValue = null;
  55. }
  56. /**
  57. * @param string $distributionValue
  58. *
  59. * @return void
  60. */
  61. public function selectShard($distributionValue)
  62. {
  63. $shardId = $this->choser->pickShard($distributionValue, $this->conn);
  64. $this->conn->connect($shardId);
  65. $this->currentDistributionValue = $distributionValue;
  66. }
  67. /**
  68. * @return string|null
  69. */
  70. public function getCurrentDistributionValue()
  71. {
  72. return $this->currentDistributionValue;
  73. }
  74. /**
  75. * @return array
  76. */
  77. public function getShards()
  78. {
  79. $params = $this->conn->getParams();
  80. $shards = array();
  81. foreach ($params['shards'] as $shard) {
  82. $shards[] = array('id' => $shard['id']);
  83. }
  84. return $shards;
  85. }
  86. /**
  87. * @param string $sql
  88. * @param array $params
  89. * @param array $types
  90. *
  91. * @return array
  92. *
  93. * @throws \RuntimeException
  94. */
  95. public function queryAll($sql, array $params, array $types)
  96. {
  97. $shards = $this->getShards();
  98. if (!$shards) {
  99. throw new \RuntimeException("No shards found.");
  100. }
  101. $result = array();
  102. $oldDistribution = $this->getCurrentDistributionValue();
  103. foreach ($shards as $shard) {
  104. $this->selectShard($shard['id']);
  105. foreach ($this->conn->fetchAll($sql, $params, $types) as $row) {
  106. $result[] = $row;
  107. }
  108. }
  109. if ($oldDistribution === null) {
  110. $this->selectGlobal();
  111. } else {
  112. $this->selectShard($oldDistribution);
  113. }
  114. return $result;
  115. }
  116. }