PageRenderTime 70ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 1ms

/library/Shanty/Mongo/Connection/Group.php

https://bitbucket.org/ilyabazhenov/speakplace
PHP | 220 lines | 118 code | 34 blank | 68 comment | 25 complexity | a7a844f814a35e23b1d20cbbfa3f5ab3 MD5 | raw file
  1. <?php
  2. require_once 'Shanty/Mongo/Connection.php';
  3. require_once 'Shanty/Mongo/Connection/Stack.php';
  4. /**
  5. * @category Shanty
  6. * @package Shanty_Mongo
  7. * @copyright Shanty Tech Pty Ltd
  8. * @license New BSD License
  9. * @author Coen Hyde
  10. */
  11. class Shanty_Mongo_Connection_Group
  12. {
  13. protected $_masters = null;
  14. protected $_slaves = null;
  15. public function __construct(array $connectionOptions = null)
  16. {
  17. $this->_masters = new Shanty_Mongo_Connection_Stack();
  18. $this->_slaves = new Shanty_Mongo_Connection_Stack();
  19. // add connections
  20. if (!is_null($connectionOptions)) {
  21. $this->addConnections($connectionOptions);
  22. }
  23. }
  24. /**
  25. * Add multiple connections at once using arrays of options
  26. *
  27. * @param array $connectionOptions
  28. */
  29. public function addConnections($connectionOptions)
  30. {
  31. if ($connectionOptions instanceof Zend_Config) {
  32. $connectionOptions = $connectionOptions->toArray();
  33. }
  34. $masters = array();
  35. $masterStackOptions = array();
  36. $slaves = array();
  37. $slaveStackOptions = array();
  38. $group = $this;
  39. $addConnections = function(Shanty_Mongo_Connection_Stack $stack, array $connections) use ($group) {
  40. foreach ($connections as $connectionData) {
  41. $options = array_intersect_key($connectionData, array_flip(Shanty_Mongo_Connection::getAvailableOptions()));
  42. $connection = new Shanty_Mongo_Connection($group->formatConnectionString($connectionData), $options);
  43. if (array_key_exists('weight', $connectionData)) $weight = (int) $connectionData['weight'];
  44. else $weight = 1;
  45. $stack->addNode($connection, $weight);
  46. }
  47. };
  48. // Lets add our masters
  49. if (array_key_exists('master', $connectionOptions)) $masters[] = $connectionOptions['master']; // single master
  50. elseif (array_key_exists('masters', $connectionOptions)) {
  51. $connectionKeys = array_filter(array_keys($connectionOptions['masters']), 'is_numeric');
  52. $masters = array_intersect_key($connectionOptions['masters'], array_flip($connectionKeys)); // only connections
  53. $masterStackOptions = array_diff_key($connectionOptions['masters'], array_flip($connectionKeys)); // only options
  54. }
  55. else $masters[] = $connectionOptions; // one server
  56. $addConnections($this->getMasters(), $masters); // Add master connections
  57. $this->getMasters()->setOptions($masterStackOptions); // Set master stack options
  58. // Lets add our slaves
  59. if (array_key_exists('slave', $connectionOptions)) $slaves[] = $connectionOptions['slave']; // single slave
  60. elseif (array_key_exists('slaves', $connectionOptions)) {
  61. $connectionKeys = array_filter(array_keys($connectionOptions['slaves']), 'is_numeric');
  62. $slaves = array_intersect_key($connectionOptions['slaves'], array_flip($connectionKeys)); // only connections
  63. $slaveStackOptions = array_diff_key($connectionOptions['slaves'], array_flip($connectionKeys)); // only options
  64. };
  65. $addConnections($this->getSlaves(), $slaves); // Add slave connections
  66. $this->getSlaves()->setOptions($slaveStackOptions); // Set slave stack options
  67. }
  68. /**
  69. * Add a connection to a master server
  70. *
  71. * @param Shanty_Mongo_Connection $connection
  72. * @param int $weight
  73. */
  74. public function addMaster(Shanty_Mongo_Connection $connection, $weight = 1)
  75. {
  76. $this->_masters->addNode($connection, $weight);
  77. }
  78. /**
  79. * Get all master connections
  80. *
  81. * @return Shanty_Mongo_Connection_Stack
  82. */
  83. public function getMasters()
  84. {
  85. return $this->_masters;
  86. }
  87. /**
  88. * Add a connection to a slaver server
  89. *
  90. * @param $connection
  91. * @param $weight
  92. */
  93. public function addSlave(Shanty_Mongo_Connection $connection, $weight = 1)
  94. {
  95. $this->_slaves->addNode($connection, $weight);
  96. }
  97. /**
  98. * Get all slave connections
  99. *
  100. * @return Shanty_Mongo_Connection_Stack
  101. */
  102. public function getSlaves()
  103. {
  104. return $this->_slaves;
  105. }
  106. /**
  107. * Get a write connection
  108. *
  109. * @return Shanty_Mongo_Connection
  110. */
  111. public function getWriteConnection()
  112. {
  113. // Select master
  114. $write = $this->_masters->selectNode();
  115. if ($write && !$write->connected) {
  116. $write->connect();
  117. }
  118. return $write;
  119. }
  120. /**
  121. * Get a read connection
  122. *
  123. * @return Shanty_Mongo_Connection
  124. */
  125. public function getReadConnection()
  126. {
  127. if (count($this->_slaves) === 0) {
  128. // If no slaves then get a master connection
  129. $read = $this->getWriteConnection();
  130. }
  131. else {
  132. // Select slave
  133. $read = $this->_slaves->selectNode();
  134. if ($read) $read->connect();
  135. }
  136. return $read;
  137. }
  138. /**
  139. * Format a connection string
  140. *
  141. * @param array $connectionOptions
  142. *
  143. */
  144. public function formatConnectionString(array $connectionOptions = array())
  145. {
  146. // See if we are dealing with a replica set
  147. if (array_key_exists('hosts', $connectionOptions)) $hosts = $connectionOptions['hosts'];
  148. else $hosts = array($connectionOptions);
  149. $connectionString = 'mongodb://';
  150. $hostStringList = array();
  151. foreach ($hosts as $hostOptions) {
  152. $hostStringList[] = static::formatHostString($hostOptions);
  153. }
  154. $connectionString .= implode(',', $hostStringList);
  155. // Set database
  156. if (isset($connectionOptions['database'])) $connectionString .= '/'.$connectionOptions['database'];
  157. return $connectionString;
  158. }
  159. /**
  160. * Format a host string
  161. *
  162. * @param $options
  163. * @return string
  164. */
  165. public function formatHostString(array $hostOptions = array())
  166. {
  167. $hostString = '';
  168. // Set username
  169. if (isset($hostOptions['username']) && !is_null($hostOptions['username'])) {
  170. $hostString .= $hostOptions['username'];
  171. // Set password
  172. if (isset($hostOptions['password']) && !is_null($hostOptions['password'])) {
  173. $hostString .= ':'.$hostOptions['password'];
  174. }
  175. $hostString .= '@';
  176. }
  177. // Set host
  178. if (isset($hostOptions['host']) && !is_null($hostOptions['host'])) $hostString .= $hostOptions['host'];
  179. else $hostString .= '127.0.0.1';
  180. // Set port
  181. $hostString .= ':';
  182. if (isset($hostOptions['port']) && !is_null($hostOptions['port'])) $hostString .= $hostOptions['port'];
  183. else $hostString .= '27017';
  184. return $hostString;
  185. }
  186. }