X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=vendor%2Fdoctrine%2Fdbal%2Flib%2FDoctrine%2FDBAL%2FSharding%2FSQLAzure%2FSQLAzureShardManager.php;fp=vendor%2Fdoctrine%2Fdbal%2Flib%2FDoctrine%2FDBAL%2FSharding%2FSQLAzure%2FSQLAzureShardManager.php;h=80ca3d928acbbbb0113f19a1e9f70712134ac9d6;hb=8b04b2d11798dee4f3e1358e4f43e97a6df851f6;hp=0000000000000000000000000000000000000000;hpb=73568cf05a785a45f94ca3f2351d9e07bf917958;p=zf2.biz%2Fapplication_blanche.git diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureShardManager.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureShardManager.php new file mode 100644 index 0000000..80ca3d9 --- /dev/null +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureShardManager.php @@ -0,0 +1,238 @@ +. + */ + +namespace Doctrine\DBAL\Sharding\SQLAzure; + +use Doctrine\DBAL\Sharding\ShardManager; +use Doctrine\DBAL\Sharding\ShardingException; +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Types\Type; + +/** + * Sharding using the SQL Azure Federations support. + * + * @author Benjamin Eberlei + */ +class SQLAzureShardManager implements ShardManager +{ + /** + * @var string + */ + private $federationName; + + /** + * @var bool + */ + private $filteringEnabled; + + /** + * @var string + */ + private $distributionKey; + + /** + * @var string + */ + private $distributionType; + + /** + * @var Connection + */ + private $conn; + + /** + * @var string + */ + private $currentDistributionValue; + + /** + * @param Connection $conn + */ + public function __construct(Connection $conn) + { + $this->conn = $conn; + $params = $conn->getParams(); + + if ( ! isset($params['sharding']['federationName'])) { + throw ShardingException::missingDefaultFederationName(); + } + + if ( ! isset($params['sharding']['distributionKey'])) { + throw ShardingException::missingDefaultDistributionKey(); + } + + if ( ! isset($params['sharding']['distributionType'])) { + throw ShardingException::missingDistributionType(); + } + + $this->federationName = $params['sharding']['federationName']; + $this->distributionKey = $params['sharding']['distributionKey']; + $this->distributionType = $params['sharding']['distributionType']; + $this->filteringEnabled = (isset($params['sharding']['filteringEnabled'])) ? (bool)$params['sharding']['filteringEnabled'] : false; + } + + /** + * Get name of the federation + * + * @return string + */ + public function getFederationName() + { + return $this->federationName; + } + + /** + * Get the distribution key + * + * @return string + */ + public function getDistributionKey() + { + return $this->distributionKey; + } + + /** + * Get the Doctrine Type name used for the distribution + * + * @return string + */ + public function getDistributionType() + { + return $this->distributionType; + } + + /** + * Enabled/Disable filtering on the fly. + * + * @param bool $flag + * @return void + */ + public function setFilteringEnabled($flag) + { + $this->filteringEnabled = (bool)$flag; + } + + /** + * {@inheritDoc} + */ + public function selectGlobal() + { + if ($this->conn->isTransactionActive()) { + throw ShardingException::activeTransaction(); + } + + $sql = "USE FEDERATION ROOT WITH RESET"; + $this->conn->exec($sql); + $this->currentDistributionValue = null; + } + + /** + * {@inheritDoc} + */ + public function selectShard($distributionValue) + { + if ($this->conn->isTransactionActive()) { + throw ShardingException::activeTransaction(); + } + + if ($distributionValue === null || is_bool($distributionValue) || !is_scalar($distributionValue)) { + throw ShardingException::noShardDistributionValue(); + } + + $platform = $this->conn->getDatabasePlatform(); + $sql = sprintf( + "USE FEDERATION %s (%s = %s) WITH RESET, FILTERING = %s;", + $platform->quoteIdentifier($this->federationName), + $platform->quoteIdentifier($this->distributionKey), + $this->conn->quote($distributionValue), + ($this->filteringEnabled ? 'ON' : 'OFF') + ); + + $this->conn->exec($sql); + $this->currentDistributionValue = $distributionValue; + } + + /** + * {@inheritDoc} + */ + public function getCurrentDistributionValue() + { + return $this->currentDistributionValue; + } + + /** + * {@inheritDoc} + */ + public function getShards() + { + $sql = "SELECT member_id as id, + distribution_name as distribution_key, + CAST(range_low AS CHAR) AS rangeLow, + CAST(range_high AS CHAR) AS rangeHigh + FROM sys.federation_member_distributions d + INNER JOIN sys.federations f ON f.federation_id = d.federation_id + WHERE f.name = " . $this->conn->quote($this->federationName); + return $this->conn->fetchAll($sql); + } + + /** + * {@inheritDoc} + */ + public function queryAll($sql, array $params = array(), array $types = array()) + { + $shards = $this->getShards(); + if (!$shards) { + throw new \RuntimeException("No shards found for " . $this->federationName); + } + + $result = array(); + $oldDistribution = $this->getCurrentDistributionValue(); + + foreach ($shards as $shard) { + $this->selectShard($shard['rangeLow']); + foreach ($this->conn->fetchAll($sql, $params, $types) as $row) { + $result[] = $row; + } + } + + if ($oldDistribution === null) { + $this->selectGlobal(); + } else { + $this->selectShard($oldDistribution); + } + + return $result; + } + + /** + * Split Federation at a given distribution value. + * + * @param mixed $splitDistributionValue + */ + public function splitFederation($splitDistributionValue) + { + $type = Type::getType($this->distributionType); + + $sql = "ALTER FEDERATION " . $this->getFederationName() . " " . + "SPLIT AT (" . $this->getDistributionKey() . " = " . + $this->conn->quote($splitDistributionValue, $type->getBindingType()) . ")"; + $this->conn->exec($sql); + } +} +