/libraries/Zend/Service/WindowsAzure/Storage/Batch.php

https://github.com/kiranatama/sagalaya · PHP · 245 lines · 98 code · 30 blank · 117 comment · 12 complexity · fa9744cc16f92874f1a6a45e0729872a MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Service_WindowsAzure
  17. * @subpackage Storage
  18. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. namespace Zend\Service\WindowsAzure\Storage;
  22. use Zend\Http\Request;
  23. use Zend\Http\Response;
  24. use Zend\Service\WindowsAzure\Exception\RuntimeException;
  25. /**
  26. * @category Zend
  27. * @package Zend_Service_WindowsAzure
  28. * @subpackage Storage
  29. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  30. * @license http://framework.zend.com/license/new-bsd New BSD License
  31. */
  32. class Batch
  33. {
  34. /**
  35. * Storage client the batch is defined on
  36. *
  37. * @var AbstractBatchStorage
  38. */
  39. protected $_storageClient = null;
  40. /**
  41. * For table storage?
  42. *
  43. * @var boolean
  44. */
  45. protected $_forTableStorage = false;
  46. /**
  47. * Base URL
  48. *
  49. * @var string
  50. */
  51. protected $_baseUrl;
  52. /**
  53. * Pending operations
  54. *
  55. * @var array
  56. */
  57. protected $_operations = array();
  58. /**
  59. * Does the batch contain a single select?
  60. *
  61. * @var boolean
  62. */
  63. protected $_isSingleSelect = false;
  64. /**
  65. * Creates a new Batch
  66. *
  67. * @param AbstractBatchStorage $storageClient Storage client the batch is defined on
  68. * @param string $baseUrl
  69. */
  70. public function __construct(AbstractBatchStorage $storageClient = null, $baseUrl = '')
  71. {
  72. $this->_storageClient = $storageClient;
  73. $this->_baseUrl = $baseUrl;
  74. $this->_beginBatch();
  75. }
  76. /**
  77. * Get base URL for creating requests
  78. *
  79. * @return string
  80. */
  81. public function getBaseUrl()
  82. {
  83. return $this->_baseUrl;
  84. }
  85. /**
  86. * Starts a new batch operation set
  87. *
  88. * @throws RuntimeException
  89. */
  90. protected function _beginBatch()
  91. {
  92. $this->_storageClient->setCurrentBatch($this);
  93. }
  94. /**
  95. * Cleanup current batch
  96. */
  97. protected function _clean()
  98. {
  99. unset($this->_operations);
  100. $this->_storageClient->setCurrentBatch(null);
  101. $this->_storageClient = null;
  102. unset($this);
  103. }
  104. /**
  105. * Enlist operation in current batch
  106. *
  107. * @param string $path Path
  108. * @param string $queryString Query string
  109. * @param string $httpVerb HTTP verb the request will use
  110. * @param array $headers x-ms headers to add
  111. * @param boolean $forTableStorage Is the request for table storage?
  112. * @param mixed $rawData Optional RAW HTTP data to be sent over the wire
  113. * @throws RuntimeException
  114. */
  115. public function enlistOperation($path = '/', $queryString = '', $httpVerb = Request::METHOD_GET, $headers = array(),
  116. $forTableStorage = false, $rawData = null)
  117. {
  118. // Set _forTableStorage
  119. if ($forTableStorage) {
  120. $this->_forTableStorage = true;
  121. }
  122. // Set _isSingleSelect
  123. if ($httpVerb == Request::METHOD_GET) {
  124. if (count($this->_operations) > 0) {
  125. throw new RuntimeException('Select operations can only be performed in an empty batch transaction.');
  126. }
  127. $this->_isSingleSelect = true;
  128. }
  129. // Clean path
  130. if (strpos($path, '/') !== 0) {
  131. $path = '/' . $path;
  132. }
  133. // Clean headers
  134. if ($headers === null) {
  135. $headers = array();
  136. }
  137. // URL encoding
  138. $path = Storage::urlencode($path);
  139. $queryString = Storage::urlencode($queryString);
  140. // Generate URL
  141. $requestUrl = $this->getBaseUrl() . $path . $queryString;
  142. // Generate $rawData
  143. if ($rawData === null) {
  144. $rawData = '';
  145. }
  146. // Add headers
  147. if ($httpVerb != Request::METHOD_GET) {
  148. $headers['Content-ID'] = count($this->_operations) + 1;
  149. if ($httpVerb != Request::METHOD_DELETE) {
  150. $headers['Content-Type'] = 'application/atom+xml;type=entry';
  151. }
  152. $headers['Content-Length'] = strlen($rawData);
  153. }
  154. // Generate $operation
  155. $operation = '';
  156. $operation .= $httpVerb . ' ' . $requestUrl . ' HTTP/1.1' . "\n";
  157. foreach ($headers as $key => $value) {
  158. $operation .= $key . ': ' . $value . "\n";
  159. }
  160. $operation .= "\n";
  161. // Add data
  162. $operation .= $rawData;
  163. // Store operation
  164. $this->_operations[] = $operation;
  165. }
  166. /**
  167. * Commit current batch
  168. *
  169. * @throws RuntimeException
  170. * @return Response
  171. */
  172. public function commit()
  173. {
  174. // Perform batch
  175. $response = $this->_storageClient->performBatch($this->_operations, $this->_forTableStorage,
  176. $this->_isSingleSelect);
  177. // Dispose
  178. $this->_clean();
  179. // Parse response
  180. $errors = null;
  181. preg_match_all('/<message (.*)>(.*)<\/message>/', $response->getBody(), $errors);
  182. // Error?
  183. if (count($errors[2]) > 0) {
  184. throw new RuntimeException('An error has occured while committing a batch: ' . $errors[2][0]);
  185. }
  186. // Return
  187. return $response;
  188. }
  189. /**
  190. * Rollback current batch
  191. */
  192. public function rollback()
  193. {
  194. // Dispose
  195. $this->_clean();
  196. }
  197. /**
  198. * Get operation count
  199. *
  200. * @return integer
  201. */
  202. public function getOperationCount()
  203. {
  204. return count($this->_operations);
  205. }
  206. /**
  207. * Is single select?
  208. *
  209. * @return boolean
  210. */
  211. public function isSingleSelect()
  212. {
  213. return $this->_isSingleSelect;
  214. }
  215. }