PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/SuperColumn.class.php

http://github.com/mjpearson/Pandra
PHP | 315 lines | 174 code | 53 blank | 88 comment | 36 complexity | 625f35945b60df6cda6b349d7a76dbd4 MD5 | raw file
  1. <?php
  2. /**
  3. * SuperColumn
  4. *
  5. * SuperColumns are special kinds of Column Containers which can contain both
  6. * Columns and have a ColumnFamily parent (implements ContainerChild)
  7. *
  8. * 'super column family' => // Super Column Family
  9. * 'my supercolumn' => { // Super Column
  10. * 'column1', // Column
  11. * 'column2', // Column
  12. * 'column3' // Column
  13. * },
  14. * 'my supercolumn2' => { // Super Column
  15. * 'column4', // Column
  16. * 'column5', // Column
  17. * 'column6' // Column
  18. * },
  19. * }
  20. *
  21. * @author Michael Pearson <pandra-support@phpgrease.net>
  22. * @copyright 2010 phpgrease.net
  23. * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
  24. * @version 0.3
  25. * @package pandra
  26. */
  27. namespace Pandra;
  28. class PandraSuperColumn extends ColumnContainer implements ContainerChild, ColumnPathable {
  29. /* @var ColumnFamily column family parent reference */
  30. private $_parent = NULL;
  31. /* @var string parent column family name, overrides parent */
  32. private $_columnFamilyName = NULL;
  33. /**
  34. * Supercolumn constructor
  35. * @param string $superName Super Column name
  36. * @param PandraSuperColumnFamily $parent
  37. */
  38. public function __construct($superName, $keyID = NULL, $keySpace = NULL, $parent = NULL, $containerType = NULL) {
  39. // SuperColumn name
  40. $this->setName($superName);
  41. // Reference parent ColumnFamilySuper
  42. if ($parent !== NULL) {
  43. $this->setParent($parent, !$parent->columnIn($superName));
  44. }
  45. parent::__construct($keyID, $keySpace, $superName, $containerType);
  46. }
  47. /**
  48. * Checks we have a bare minimum attributes on the entity, to perform a columnpath search
  49. * @param string $keyID optional overriding row key
  50. * @return bool columnpath looks ok
  51. */
  52. public function pathOK($keyID = NULL) {
  53. if ($this->_parent === NULL) {
  54. return parent::pathOK($keyID);
  55. }
  56. return $this->_parent->pathOK($keyID);
  57. }
  58. /**
  59. * Save all columns in this loaded columnfamily
  60. * @return void
  61. */
  62. public function save($consistencyLevel = NULL) {
  63. if (!$this->isModified()) return FALSE;
  64. $ok = $this->pathOK();
  65. if ($ok) {
  66. if ($this->isDeleted()) {
  67. $columnPath = new \cassandra_ColumnPath();
  68. $columnPath->column_family = $this->getColumnFamilyName();
  69. $columnPath->super_column = $this->getName();
  70. $ok = Core::deleteColumnPath($this->getKeySpace(),
  71. $this->getKeyID(),
  72. $columnPath,
  73. NULL,
  74. $consistencyLevel);
  75. } else {
  76. $deletions = array();
  77. $insertions = array();
  78. $selfKey = $this->getKeyID();
  79. $selfName = $this->getName();
  80. $selfCFName = $this->getColumnFamilyName();
  81. // build mutation
  82. $map = array($selfKey => array($selfCFName => array()));
  83. $ptr = &$map[$selfKey][$selfCFName];
  84. $this->bindTimeModifiedColumns();
  85. $modifiedColumns = $this->getModifiedColumns();
  86. if (!empty($modifiedColumns)) {
  87. foreach ($modifiedColumns as &$cObj) {
  88. if ($cObj->isDeleted()) {
  89. $deletions[] = $cObj->getName();
  90. } else {
  91. $insertions[] = $cObj;
  92. }
  93. }
  94. if (!empty($deletions)) {
  95. $p = new SlicePredicate(PandraSlicePredicate::TYPE_COLUMNS, $deletions);
  96. $sd = new \cassandra_Deletion(array('timestamp' => Core::getTime(), 'predicate' => $p));
  97. $ptr[] = new \cassandra_Mutation(array('deletion' => $sd));
  98. }
  99. if (!empty($insertions)) {
  100. $sc = new \cassandra_SuperColumn(array('name' => $selfName, 'columns' => $insertions));
  101. $csc = new \cassandra_ColumnOrSuperColumn(array('super_column' => $sc));
  102. $ptr[] = new \cassandra_Mutation(array('column_or_supercolumn' => $csc));
  103. }
  104. $ok = Core::batchMutate($this->getKeySpace(), $map, $consistencyLevel);
  105. }
  106. }
  107. if ($ok) {
  108. $this->reset();
  109. } else {
  110. $this->registerError(Core::$lastError);
  111. }
  112. }
  113. return $ok;
  114. }
  115. /**
  116. * Loads a SuperColumn for key
  117. *
  118. * @param string $keyID optional row key
  119. * @param int $consistencyLevel cassandra consistency level
  120. * @return bool loaded OK
  121. */
  122. public function load($keyID = NULL, $consistencyLevel = NULL) {
  123. if ($keyID === NULL) $keyID = $this->getKeyID();
  124. $ok = $this->pathOK($keyID);
  125. $this->setLoaded(FALSE);
  126. if ($ok) {
  127. $autoCreate = $this->getAutoCreate();
  128. $predicate = new \cassandra_SlicePredicate();
  129. // if autocreate is turned on, get latest limited everything
  130. if ($autoCreate) {
  131. $predicate->slice_range = new \cassandra_SliceRange();
  132. $predicate->slice_range->start = $this->getStart();
  133. $predicate->slice_range->finish = $this->getFinish();
  134. $predicate->slice_range->count = $this->getLimit();
  135. $predicate->slice_range->reversed = $this->getReversed();
  136. $result = Core::getCFSlice(
  137. $this->getKeySpace(),
  138. $keyID,
  139. new \cassandra_ColumnParent(array(
  140. 'column_family' => $this->getColumnFamilyName(),
  141. 'super_column' => $this->getName())),
  142. $predicate,
  143. $consistencyLevel);
  144. // otherwise by defined columns (slice query)
  145. } else {
  146. $predicate->column_names = $this->getColumnNames();
  147. $result = Core::getCFSliceMulti(
  148. $this->getKeySpace(),
  149. array($keyID),
  150. $predicate,
  151. new \cassandra_ColumnParent(
  152. array(
  153. 'column_family' => $this->getColumnFamilyName(),
  154. 'super_column' => $this->getName())),
  155. $consistencyLevel);
  156. $result = $result[$keyID];
  157. }
  158. if (!empty($result)) {
  159. $this->init();
  160. $this->setLoaded($this->populate($result, $autoCreate));
  161. if ($this->isLoaded()) $this->setKeyID($keyID);
  162. } else {
  163. $this->registerError(Core::$lastError);
  164. }
  165. }
  166. return ($ok && $this->isLoaded());
  167. }
  168. /**
  169. * Sets parent Column Container
  170. * @param ColumnContainer $parent SuperColumnFamily container object, or NULL
  171. */
  172. public function setParent(ColumnContainer $parent, $bindToParent = TRUE) {
  173. if (!($parent instanceof PandraSuperColumnFamily))
  174. throw new RuntimeException('Parent must be an instance of PandraSuperColumnFamily');
  175. if ($bindToParent) $parent->addSuperColumnObj($this);
  176. // unbind existing parent
  177. $this->detach();
  178. $this->_parent = $parent;
  179. }
  180. /**
  181. * Gets the current working parent column family
  182. * @return <type>
  183. */
  184. public function getParent() {
  185. return $this->_parent;
  186. }
  187. /**
  188. * Nullifies a parent
  189. */
  190. public function disown($localDetach = TRUE) {
  191. if ($localDetach) $this->detach();
  192. $this->_parent = NULL;
  193. }
  194. /**
  195. * Calls parent unset for this column
  196. */
  197. public function detach() {
  198. if ($this->_parent !== NULL) {
  199. $this->_parent->unsetColumn($this->getName());
  200. }
  201. }
  202. /**
  203. * accessor, parent column family name
  204. * @return string container name
  205. */
  206. public function getColumnFamilyName() {
  207. $parent = $this->getParent();
  208. if ($this->_columnFamilyName === NULL && $parent !== NULL) {
  209. return $parent->getName();
  210. }
  211. return $this->_columnFamilyName;
  212. }
  213. /**
  214. * mutator, container name
  215. * @param string $name new name
  216. */
  217. public function setColumnFamilyName($columnFamilyName) {
  218. $this->_columnFamilyName = $columnFamilyName;
  219. }
  220. /**
  221. * keyID accessor if local member has not been set, attempts to return the set parents attribute instead
  222. * @return string
  223. */
  224. public function getKeyID() {
  225. $parent = $this->getParent();
  226. if ($this->_keyID === NULL && $parent !== NULL) {
  227. return $parent->getKeyID();
  228. }
  229. return $this->_keyID;
  230. }
  231. /**
  232. * keySpace accessor if local member has not been set, attempts to return the set parents attribute instead
  233. * @return string
  234. */
  235. public function getKeySpace() {
  236. $parent = $this->getParent();
  237. if ($this->_keySpace === NULL && $parent !== NULL) {
  238. return $parent->getKeySpace();
  239. }
  240. return $this->_keySpace;
  241. }
  242. /**
  243. * Creates an error entry in this column and propogate to parent
  244. * @param string $errorStr error string
  245. */
  246. public function registerError($errorStr) {
  247. if (!empty($errorStr)) {
  248. array_push($this->errors, $errorStr);
  249. if ($this->_parent !== NULL) $this->_parent->registerError($errorStr);
  250. }
  251. }
  252. public function _getName() {
  253. $parent = $this->getParent();
  254. if ($parent !== NULL) {
  255. if ($parent->getType() == self::TYPE_UUID) {
  256. return UUID::toStr($this->_name);
  257. }
  258. }
  259. return parent::getName();
  260. }
  261. }
  262. ?>