forked from Sammaye/MongoYii
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEMongoCursor.php
131 lines (110 loc) · 3.97 KB
/
EMongoCursor.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<?php
/**
* EMongoCursor
*
* Represents the Yii edition to the MongoCursor and allows for lazy loading of objects.
*
* This class does not support eager loading by default, in order to use eager loading you should look into using this
* classes reponse with iterator_to_array().
*
* I did try originally to make this into a active data provider and use this for two fold operations but the cactivedataprovider would extend
* a lot for the cursor and the two took quite different constructors.
*/
class EMongoCursor implements Iterator, Countable{
public $criteria = array();
public $modelClass;
public $model;
private $cursor = array();
private $current;
private $isCertainFields = false;
/**
* The cursor constructor
* @param array|MongoCursor $condition Either a condition array (without sort,limit and skip) or a MongoCursor Object
* @param string $class the class name for the active record
*/
public function __construct($modelClass,$criteria=array(), $fields = array()) {
if(!empty($fields))
$this->isCertainFields = true;
if(is_string($modelClass)){
$this->modelClass=$modelClass;
$this->model=EMongoDocument::model($this->modelClass);
}elseif($modelClass instanceof EMongoDocument){
$this->modelClass=get_class($modelClass);
$this->model=$modelClass;
}
if($criteria instanceof MongoCursor){
$this->cursor = $criteria;
$this->cursor->reset();
}elseif($criteria instanceof EMongoCriteria){
$this->criteria = $criteria;
$this->cursor = $this->model->getCollection()->find($criteria->condition, $fields)->sort($criteria->sort);
if($criteria->skip != 0)
$this->cursor->skip($criteria->skip);
if($criteria->limit!=0)
$this->cursor->limit($criteria->limit);
}else{
// Then we are doing an active query
$this->criteria = $criteria;
$this->cursor = $this->model->getCollection()->find($criteria, $fields);
}
return $this; // Maintain chainability
}
/**
* If we call a function that is not implemented here we try and pass the method onto
* the MongoCursor class, otherwise we produce the error that normally appears
*
* @param $method
* @param $params
*/
public function __call($method, $params = array()){
if($this->cursor() instanceof MongoCursor && method_exists($this->cursor(), $method)){
return call_user_func_array(array($this->cursor(), $method), $params);
}
throw new EMongoException(Yii::t('yii', "Call to undefined function {method} on the cursor"), array('{method}' => $method));
}
/**
* Holds the MongoCursor
*/
public function cursor(){
return $this->cursor;
}
/**
* Gets the active record for the current row
*/
public function current() {
if($this->model === null)
throw new EMongoException(Yii::t('yii', "The MongoCursor must have a model"));
if($this->isCertainFields)
return $this->current=$this->cursor()->current();
else
return $this->current=$this->model->populateRecord($this->cursor()->current());
}
public function count($takeSkip = false /* Was true originally but it was to change the way the driver worked which seemed wrong */){
return $this->cursor()->count($takeSkip);
}
public function sort(array $fields){
$this->cursor()->sort($fields);
return $this;
}
public function skip($num = 0){
$this->cursor()->skip($num);
return $this;
}
public function limit($num = 0){
$this->cursor()->limit($num);
return $this;
}
public function rewind() {
$this->cursor()->rewind();
return $this;
}
public function key() {
return $this->cursor()->key();
}
public function next() {
return $this->cursor()->next();
}
public function valid() {
return $this->cursor()->valid();
}
}