|
|
- <?php
- namespace SparkLib;
-
- use \MongoDBI as Mongo;
- use \SparkLib\Iterator;
-
- /**
- * Class that creates a nice interface for accessing Mongo
- */
- class MongoFinder extends Iterator {
-
- protected $_mongo;
- protected $_mongoCursor;
- protected $_collection;
- protected $_class;
- protected $_query;
- protected $_where = [];
- protected $_sort = [];
- protected $_row;
- protected $_whereWaiting = false;
- protected $_sortWaiting = false;
- protected $_paramsChanged = false;
- protected $_resultCount;
-
- /**
- * Create new instance and store the collection name to be used in find()
- *
- * @param string $collection - mongo collection in which search happens
- * @param string $class - class in which to wrap mongo instance
- *
- * @return MongoFinder
- */
- public function __construct($collection, $class) {
- $this->_mongo = Mongo::getInstance();
- $this->_collection = $collection;
- $this->_class = $class;
- return $this;
- }
-
- /**
- * checks to see if you called either sortBy('something') or where('something')
- * without calling asc()/desc() or eq()/is() respectively
- *
- * @return void
- */
- protected function _checkWaiting() {
- if ($this->_whereWaiting !== false)
- throw new \Exception('Mongo WHERE waiting completion');
-
- if ($this->_sortWaiting !== false)
- throw new \Exception('Mongo SORT waiting completion');
- }
-
- /**
- * adds parameter to where array that will be used in find()
- *
- * @param string $key - the key in the mongodb for which you want to search
- *
- * @return MongoFinder
- */
- public function where($key) {
- $this->_checkWaiting();
-
- $this->_where[$key] = true;
- $this->_whereWaiting = $key;
- $this->_paramsChanged = true;
- return $this;
- }
-
- /**
- * adds parameter to where array that will be used in find()
- *
- * @param mixed $value - the value of the $key previously set in where()
- * @param string $comparison (optional) comparison to make between $key and $value
- *
- * @return MongoFinder
- */
- public function is($value, $comparison = false) {
- if (! $this->_where[$this->_whereWaiting])
- throw new \Exception('Mongo WHERE not called');
-
- if (! $comparison) {
- $comparison = '=';
- }
-
- switch($comparison) {
- case '=':
- $this->_where[$this->_whereWaiting] = $value;
- break;
- case '>':
- $this->_where[$this->_whereWaiting] = [ '$gt' => $value ];
- break;
- case '>=':
- $this->_where[$this->_whereWaiting] = [ '$gte' => $value ];
- break;
- case '<':
- $this->_where[$this->_whereWaiting] = [ '$lt' => $value ];
- break;
- case '<=':
- $this->_where[$this->_whereWaiting] = [ '$lte' => $value ];
- break;
- case 'in':
- $this->_where[$this->_whereWaiting] = [ '$in' => $value ];
- break;
- }
- $this->_paramsChanged = true;
- $this->_whereWaiting = false;
-
- return $this;
- }
-
- /**
- * adds parameter to where array that will be used in find()
- *
- * @param string $regex - the regex to match the against $key previously set in where()
- * @param string $flags - optional, regex search flags
- *
- * @return MongoFinder
- */
- public function isLike($regex, $flags = '') {
- if (! $this->_where[$this->_whereWaiting])
- throw new \Exception('Mongo WHERE not called');
-
- $this->_where[$this->_whereWaiting] = [ '$regex' => "$regex", '$options' => "$flags" ];
-
- $this->_paramsChanged = true;
- $this->_whereWaiting = false;
-
- return $this;
- }
-
-
- /**
- * adds parameter to where array that will be used in find() use for values
- * you DO NOT want to be true
- *
- * example:
- * where('cat_attitude')->not('angry'); // cat_attitude != angry
- * where('cat_weight')->not(20, '>'); // ! cat_weight > 20
- *
- * @param mixed $value - the value of the $key previously set in where()
- * @param string $comparison (optional) comparison to make between $key and $value
- *
- * @return MongoFinder
- */
- public function isNot($value, $comparison = false) {
- if (! $this->_where[$this->_whereWaiting])
- throw new \Exception('Mongo WHERE not called');
-
- if(! $comparison) {
- $comparison = '=';
- }
-
- switch($comparison) {
- case '=':
- if (is_array($value))
- $this->_where[$this->_whereWaiting] = [ '$not' => $value ];
- else
- $this->_where[$this->_whereWaiting] = [ '$not' => new MongoRegex('/^' . $value . '$/') ];
- break;
- case '>':
- $this->_where[$this->_whereWaiting] = [ '$not' => [ '$gt' => $value ] ];
- break;
- case '>=':
- $this->_where[$this->_whereWaiting] = [ '$not' => [ '$gte' => $value ] ];
- break;
- case '<':
- $this->_where[$this->_whereWaiting] = [ '$not' => [ '$lt' => $value ] ];
- break;
- case '<=':
- $this->_where[$this->_whereWaiting] = [ '$not' => [ '$lte' => $value ] ];
- break;
- }
- $this->_paramsChanged = true;
- $this->_whereWaiting = false;
-
- return $this;
- }
-
- /**
- * alias for is($value, '=')
- *
- * @param mixed $value value you're checking against $key set in where()
- *
- * @return MongoFinder
- */
- public function eq($value) {
- $this->_paramsChanged = true;
- return $this->is($value, '=');
- }
-
- /**
- * alias for is($value, 'in')
- *
- * @param mixed $value value you're checking against $key set in where()
- *
- * @return MongoFinder
- */
- public function in($value) {
- if(! is_array($value))
- return $this;
-
- $this->_paramsChanged = true;
- return $this->is($value, 'in');
- }
-
- /**
- * alias for is($value, [ '$exists' => false ])
- *
- * @return MongoFinder
- */
- public function isNull() {
- $this->_paramsChanged = true;
- return $this->is([ '$exists' => false ], '=');
- }
-
- /**
- * alias for is($value, [ '$exists' => true ])
- *
- * @return MongoFinder
- */
- public function isNotNull() {
- $this->_paramsChanged = true;
- return $this->is([ '$exists' => true ], '=');
- }
-
- /**
- * how to sort results of search
- *
- * @param mixed $order - if it's an array format: [ $sortKey => 1 ] if it
- * is a string then format: sortkey
- *
- * @return MongoFinder
- */
- public function orderBy($order) {
- $this->_checkWaiting();
-
- if (is_array($order)) {
- foreach($order as $k => $v) {
- switch($v) {
- case 1:
- case -1:
- $this->_sort[$k] = $v;
- break;
- case 'ASC':
- case 'asc':
- $this->_sort[$k] = -1;
- break;
- case 'DESC':
- case 'desc':
- $this->_sort[$k] = 1;
- break;
- }
- }
- } else {
- $this->_sort[$order] = true;
- $this->_sortWaiting = $order;
- }
-
- $this->_paramsChanged = true;
- return $this;
- }
-
- /**
- * sort by asc, should be proceeded with a call to sort()
- *
- * @return MongoFinder
- */
- public function asc() {
- if (! $this->_sort[$this->_sortWaiting])
- throw new \Exception('Mongo SORT not called');
-
- $this->_sort[$this->_sortWaiting] = -1;
-
- $this->_sortWaiting = false;
- $this->_paramsChanged = true;
- return $this;
- }
-
- /**
- * sort by desc, should be proceeded with a call to sort()
- *
- * @return MongoFinder
- */
- public function desc() {
- if (! $this->_sort[$this->_sortWaiting])
- throw new \Exception('Mongo SORT not called');
-
- $this->_sort[$this->_sortWaiting] = 1;
-
- $this->_sortWaiting = false;
- $this->_paramsChanged = true;
- return $this;
- }
-
- /**
- * Moves internal pointer forward once
- *
- * @return MongoFinder
- */
- public function next() {
- $this->_checkWaiting();
-
- if (! isset($this->_mongoCursor) || $this->_paramsChanged)
- $this->find();
-
- $this->_mongoCursor->next();
-
- return $this;
- }
-
- /**
- * Moves internal pointer forward by $int
- *
- * @param int $int - number of times to skip the internal pointer
- *
- * @return MongoFinder
- */
- public function skip($int) {
- $this->_checkWaiting();
-
- if (! isset($this->_mongoCursor) || $this->_paramsChanged)
- $this->find();
-
- $this->_mongoCursor->skip($int);
-
- return $this;
- }
-
- /**
- * Moves internal pointer to beginning
- *
- * @return MongoFinder
- */
- public function rewind() {
- $this->_checkWaiting();
-
- if (! isset($this->_mongoCursor) || $this->_paramsChanged)
- $this->find();
-
- $this->_mongoCursor->rewind();
- return $this;
- }
-
- /**
- * alias for getNext
- *
- * @return \Spark\$collection-wrapped Mongo thing
- */
- public function getOne() {
- return $this->getNext();
- }
-
- /**
- * Returns the current result and iterates the pointer
- *
- * @return \Spark\$collection-wrapped mongo-thing
- */
- public function getNext () {
- $this->_checkWaiting();
-
- if (! isset($this->_mongoCursor) || $this->_paramsChanged)
- $this->find();
-
- $result = $this->current();
-
- if (false !== $result)
- $this->next();
-
- return $result;
- }
-
- /**
- * Returns the current result at pointer
- *
- * @return \Spark\$collection-wrapped mongo-thing
- */
- public function current() {
- $this->_checkWaiting();
-
- if (! isset($this->_mongoCursor) || $this->_paramsChanged)
- $this->find();
-
- if (! $this->_mongoCursor->current())
- return false;
-
- return new $this->_class($this->_mongoCursor->current());
- }
-
- /**
- * get a count of the result ste
- *
- * @return int
- */
- public function count() {
- if (! isset($this->_mongoCursor) || $this->_paramsChanged) {
- $this->find();
- $this->_resultCount = null;
- }
-
- if (! isset($this->_resultCount))
- $this->_resultCount = $this->_mongoCursor->count();
-
- return $this->_resultCount;
- }
-
- /**
- * Actually does the search on mongo and iterates the pointer so it's on a result
- *
- * @return MongoFinder
- */
- public function find() {
- $this->_checkWaiting();
-
- $collection = $this->_collection;
-
- $this->_mongoCursor = $this->_mongo->$collection->find($this->_where)->sort($this->_sort);
- $this->_mongoCursor->next();
-
- // Reset params so no new find runs
- $this->_paramsChanged = false;
-
- return $this;
- }
-
- /**
- * Resets all query info
- */
- public function reset() {
- $this->_where = [];
- $this->_sort = [];
- $this->_whereWaiting = false;
- $this->_sortWaiting = false;
- $this->_paramsChanged = false;
- $this->_resultCount = null;
- $this->_row = null;
- $this->_query = null;
- $this->_mongoCursor = null;
- }
-
- /**
- * Dumps mongo query as string
- *
- * @return string
- */
- public function getQuery() {
- return 'db.' . $this->_collection . '.find(' . json_encode($this->_where) . ').sort(' . json_encode($this->_sort) . ').pretty()';
- }
-
- /**
- * Makes sure the current result is an instance of the class passed in
- *
- * @return boolean
- */
- public function valid () {
- return $this->_mongoCursor->current() instanceof $this->_class;
- }
-
- /**
- * Returns the mongo id of the mongo entity currently under the pointer
- *
- * @return string
- */
- public function key () {
- if (! isset($this->_mongoCursor) || $this->_paramsChanged)
- $this->find();
-
- return (string) $this->current()->id();
- }
- }
|