PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/mongodb-morph/src/Morph/Query/Property.php

http://mongodb-morph.googlecode.com/
PHP | 373 lines | 141 code | 36 blank | 196 comment | 8 complexity | 790445bf9791868514651d7b80c302d0 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /**
  3. * @package Morph
  4. * @subpackage Query
  5. * @author Jonathan Moss <xirisr@gmail.com>
  6. * @copyright 2009 Jonathan Moss
  7. * @version SVN: $Id$
  8. */
  9. /**
  10. * Represents a series of constraints to be applied to a property when querying
  11. *
  12. *
  13. * @package Morph
  14. * @subpackage Query
  15. */
  16. class Morph_Query_Property
  17. {
  18. /**
  19. * Internal flag to mark the mode as singular constraint
  20. * @var string
  21. */
  22. const MODE_SINGULAR = 'SINGULAR';
  23. /**
  24. * Internal flag to mark the mode as compound constraint
  25. * @var string
  26. */
  27. const MODE_COMPOUND = 'COMPOUND';
  28. /**
  29. * @var Morph_Query
  30. */
  31. private $query;
  32. /**
  33. * @var mixed
  34. */
  35. private $constraints;
  36. /**
  37. * @var string
  38. */
  39. private $mode;
  40. /**
  41. * @var int
  42. */
  43. private $sortDirection;
  44. /**
  45. * Create a new property object
  46. *
  47. * @param $query
  48. * @return Morph_Query_Property
  49. */
  50. public function __construct(Morph_Query $query)
  51. {
  52. $this->query = $query;
  53. $this->constraints = array();
  54. }
  55. ///////////////////////////////////////
  56. // WRAPPER FOR Morph_Query FUNCTIONS //
  57. ///////////////////////////////////////
  58. /**
  59. * Adds a new property
  60. *
  61. * @param string $propertyName
  62. * @return Morph_Query_Property
  63. */
  64. public function property($propertyName)
  65. {
  66. return $this->query->property($propertyName);
  67. }
  68. /**
  69. * Sets the limit for the result set
  70. *
  71. * @param int $limit
  72. * @return Morph_Query
  73. */
  74. public function limit($limit)
  75. {
  76. return $this->query->limit($limit);
  77. }
  78. /**
  79. * Skips the first $numberToSkip results that would normally be returned
  80. *
  81. * @param int $numberToSkip
  82. * @return Morph_Query
  83. */
  84. public function skip($numberToSkip)
  85. {
  86. return $this->query->skip($numberToSkip);
  87. }
  88. //////////////////////////
  89. // CONSTRAINT FUNCTIONS //
  90. //////////////////////////
  91. /**
  92. * Sets an equals constraint
  93. *
  94. * Note that you cannot use equals in conjunction with the other constraint types.
  95. *
  96. * @param mixed $value
  97. * @return Morph_Query_Property
  98. */
  99. public function equals($value)
  100. {
  101. $this->setSingularConstraint($value);
  102. return $this;
  103. }
  104. /**
  105. * adds a greater than constraint
  106. *
  107. * @param mixed $value
  108. * @return Morph_Query_Property
  109. */
  110. public function greaterThan($value)
  111. {
  112. $this->addCompoundConstraint('$gt', $value);
  113. return $this;
  114. }
  115. /**
  116. * adds a greater than or equal to constraint
  117. *
  118. * @param mixed $value
  119. * @return Morph_Query_Property
  120. */
  121. public function greaterThanOrEqualTo($value)
  122. {
  123. $this->addCompoundConstraint('$gte', $value);
  124. return $this;
  125. }
  126. /**
  127. * adds a less than constraint
  128. *
  129. * @param mixed $value
  130. * @return Morph_Query_Property
  131. */
  132. public function lessThan($value)
  133. {
  134. $this->addCompoundConstraint('$lt', $value);
  135. return $this;
  136. }
  137. /**
  138. * adds a less than or equal to constraint
  139. *
  140. * @param mixed $value
  141. * @return Morph_Query_Property
  142. */
  143. public function lessThanOrEqualTo($value)
  144. {
  145. $this->addCompoundConstraint('$lte', $value);
  146. return $this;
  147. }
  148. /**
  149. * adds a not equal to constraint
  150. *
  151. * @param mixed $value
  152. * @return Morph_Query_Property
  153. */
  154. public function notEqualTo($value)
  155. {
  156. $this->addCompoundConstraint('$ne', $value);
  157. return $this;
  158. }
  159. /**
  160. * adds an in array constraint
  161. *
  162. * @param array $value
  163. * @return Morph_Query_Property
  164. */
  165. public function in(array $value)
  166. {
  167. $this->addCompoundConstraint('$in', $value);
  168. return $this;
  169. }
  170. /**
  171. * adds a not in array constraint
  172. *
  173. * @param array $value
  174. * @return Morph_Query_Property
  175. */
  176. public function notIn(array $value)
  177. {
  178. $this->addCompoundConstraint('$nin', $value);
  179. return $this;
  180. }
  181. /**
  182. * adds a constraint where all values in $value must be in this property
  183. *
  184. * This property must be an array
  185. *
  186. * @param array $value
  187. * @return Morph_Query_Property
  188. */
  189. public function all(array $value)
  190. {
  191. $this->addCompoundConstraint('$all', $value);
  192. return $this;
  193. }
  194. /**
  195. * Adds a regular expression constraint
  196. *
  197. * @param string $regex
  198. * @return Morph_Query_Property
  199. */
  200. public function regex($regex)
  201. {
  202. $this->setSingularConstraint(new MongoRegex($regex));
  203. return $this;
  204. }
  205. /**
  206. * Adds a like constraint
  207. *
  208. * Convenience wrapper for regex. Adds a wild card to the
  209. * start and end of the query $value.
  210. *
  211. * e.g. 'bob' is turned into '.*bob.*'
  212. *
  213. * This is probably really in-efficient so I would recommend
  214. * using regex directly with a custom written pattern.
  215. *
  216. * @param string $value
  217. * @return Morph_Query_Property
  218. */
  219. public function like($value)
  220. {
  221. $term = '/.*' . $value . '.*/i';
  222. return $this->regex($term);
  223. }
  224. /**
  225. * Adds a constraint that this property must have $value entries
  226. *
  227. * This property must be an array
  228. *
  229. * @param int $value
  230. * @return Morph_Query_Property
  231. */
  232. public function size($value)
  233. {
  234. $this->addCompoundConstraint('$size', (int) $value);
  235. return $this;
  236. }
  237. /**
  238. * Adds a constraint that a property must exist or not
  239. *
  240. * @param boolean $exists
  241. * @return Morph_Query_Property
  242. */
  243. public function exists($exists = true)
  244. {
  245. $this->addCompoundConstraint('$exists', (bool)$exists);
  246. return $this;
  247. }
  248. /**
  249. * Sets the sort direction if needed
  250. *
  251. * @param $direction
  252. * @return Morph_Query_Property
  253. */
  254. public function sort($direction = Morph_Enum::DIRECTION_ASC)
  255. {
  256. switch ($direction) {
  257. case Morph_Enum::DIRECTION_ASC:
  258. $this->sortDirection = Morph_Enum::DIRECTION_ASC;
  259. break;
  260. case Morph_Enum::DIRECTION_DESC:
  261. $this->sortDirection = Morph_Enum::DIRECTION_DESC;
  262. break;
  263. default:
  264. throw new InvalidArgumentException("Sort direction should be -1 or 1");
  265. }
  266. return $this;
  267. }
  268. /**
  269. * Returns an array of all associated constraints
  270. *
  271. * @return array
  272. */
  273. public function getConstraints()
  274. {
  275. return $this->constraints;
  276. }
  277. /**
  278. * Returns the sort direction of this property
  279. *
  280. * @return int
  281. */
  282. public function getSort()
  283. {
  284. return $this->sortDirection;
  285. }
  286. //////////////////////////////////////////
  287. // INTERNAL CONSTRAINT HELPER FUNCTIONS //
  288. //////////////////////////////////////////
  289. /**
  290. * Adds a new compound constraint
  291. *
  292. * @param string $type
  293. * @param mixed $value
  294. * @return void
  295. * @throws RuntimeException if this property is in singular constraint mode
  296. */
  297. private function addCompoundConstraint($type, $value)
  298. {
  299. if ($this->isPermitted(self::MODE_COMPOUND)) {
  300. $this->constraints[$type] = $value;
  301. } else {
  302. throw new RuntimeException("You cannot use a a property in both compound and singular modes");
  303. }
  304. }
  305. /**
  306. * Sets a value of a singular constraint
  307. *
  308. * @param mixed $value
  309. * @return void
  310. * @throws RuntimeException if this property is in compound constraint mode
  311. */
  312. private function setSingularConstraint($value)
  313. {
  314. if ($this->isPermitted(self::MODE_SINGULAR)) {
  315. $this->constraints = $value;
  316. } else {
  317. throw new RuntimeException("You cannot use a a property in both compound and singular modes");
  318. }
  319. }
  320. /**
  321. * Returns true only if the specified mode is permitted
  322. *
  323. * @param string $mode
  324. * @return boolean
  325. */
  326. private function isPermitted($mode)
  327. {
  328. $isPermitted = true;
  329. if (empty($this->mode)) {
  330. $this->mode = $mode;
  331. }
  332. if ($this->mode != $mode) {
  333. $isPermitted = false;
  334. }
  335. return $isPermitted;
  336. }
  337. }