1: <?php
2:
3: namespace PHPixie\Database\Driver\Mongo;
4:
5: class Parser extends \PHPixie\Database\Parser
6: {
7: protected $conditionsParser;
8:
9: public function __construct($database, $driver, $config, $conditionsParser)
10: {
11: parent::__construct($database, $driver, $config);
12: $this->conditionsParser = $conditionsParser;
13: }
14:
15: public function parse($query)
16: {
17: $runner = $this->driver->runner();;
18: switch ($query->type()) {
19: case 'select':
20: return $this->selectQuery($query, $runner);
21: case 'selectSingle':
22: return $this->selectSingleQuery($query, $runner);
23: case 'insert':
24: return $this->insertQuery($query, $runner);
25: case 'update':
26: return $this->updateQuery($query, $runner);
27: case 'delete':
28: return $this->deleteQuery($query, $runner);
29: case 'count':
30: return $this->countQuery($query, $runner);
31: default:
32: throw new \PHPixie\Database\Exception\Parser("Query type '{$query->type()}' is not supported");
33: }
34: }
35:
36: protected function selectQuery($query, $runner)
37: {
38: $this->chainCollection($query, $runner);
39: $fields = $query->getFields();
40: $conditions = $this->conditionsParser->parse($query->getWhereConditions());
41: $limit = $query->getLimit();
42: $offset = $query->getOffset();
43: $order = $query->getOrderBy();
44: $fieldKeys = $this->fieldKeys($fields);
45:
46: $runner->chainMethod('find', array($conditions, $fieldKeys));
47: if (!empty($order)) {
48: $ordering = array();
49: foreach ($order as $orderBy) {
50: $ordering[$orderBy->field()] = $orderBy->direction() === 'asc' ? 1 : -1;
51: }
52: $runner->chainMethod('sort', array($ordering));
53: }
54:
55: if ($limit !== null)
56: $runner->chainMethod('limit', array($limit));
57: if ($offset !== null)
58: $runner->chainMethod('skip', array($offset));
59:
60: return $runner;
61: }
62:
63: protected function fieldKeys($fields)
64: {
65: return array_fill_keys($fields, 1);
66: }
67:
68: protected function selectSingleQuery($query, $runner)
69: {
70: $this->chainCollection($query, $runner);
71: $fields = $query->getFields();
72: $conditions = $this->conditionsParser->parse($query->getWhereConditions());
73: $fieldKeys = $this->fieldKeys($fields);
74:
75: $runner->chainMethod('findOne', array($conditions, $fieldKeys));
76:
77: return $runner;
78: }
79:
80: protected function insertQuery($query, $runner)
81: {
82: $this->chainCollection($query, $runner);
83:
84: if (($data = $query->getBatchData()) !== null) {
85: $runner->chainMethod('batchInsert', array($data));
86: } elseif (($data = $query->getData()) !== null) {
87: $runner->chainMethod('insert', array($data));
88: }else
89: throw new \PHPixie\Database\Exception\Parser("No data set for insertion");
90:
91: return $runner;
92: }
93:
94: protected function updateQuery($query, $runner)
95: {
96: $this->chainCollection($query, $runner);
97:
98: $modifiers = array(
99: '$set' => $query->getSet(),
100: '$unset' => $this->fieldKeys($query->getUnset()),
101: '$inc' => $query->getIncrement()
102: );
103:
104: $data = array();
105: foreach ($modifiers as $key=>$value) {
106: if(!empty($value))
107: $data[$key] = $value;
108: }
109:
110: if (empty($data))
111: throw new \PHPixie\Database\Exception\Parser("No modifiers specified for update");
112:
113: $conditions = $this->conditionsParser->parse($query->getWhereConditions());
114: $runner->chainMethod('update', array($conditions, $data, array('multiple' => true)));
115:
116: return $runner;
117: }
118:
119: protected function deleteQuery($query, $runner)
120: {
121: $this->chainCollection($query, $runner);
122: $conditions = $this->conditionsParser->parse($query->getWhereConditions());
123: $runner->chainMethod('remove', array($conditions));
124:
125: return $runner;
126: }
127:
128: protected function countQuery($query, $runner)
129: {
130: $this->chainCollection($query, $runner);
131: $conditions = $this->conditionsParser->parse($query->getWhereConditions());
132:
133: $empty = true;
134: foreach($conditions as $key => $value) {
135: $empty = false;
136: break;
137: }
138:
139: if (!$empty) {
140: $runner->chainMethod('find', array($conditions));
141: }
142: $runner->chainMethod('count');
143:
144: return $runner;
145: }
146:
147: protected function chainCollection($query, $runner)
148: {
149: if (($collection = $query->getCollection()) !== null) {
150: $runner->chainProperty($collection);
151: }else
152: throw new \PHPixie\Database\Exception\Parser("You must specify a collection for this query.");
153: }
154: }
155: