1: <?php
2:
3: namespace PHPixie\Database\Query\Implementation;
4:
5: abstract class Builder
6: {
7: protected $conditions;
8: protected $valueBuilder;
9: protected $values = array();
10: protected $arrays = array();
11: protected $conditionContainers = array();
12: protected $defaultContainer;
13:
14: public function __construct($conditions, $valueBuilder)
15: {
16: $this->conditions = $conditions;
17: $this->valueBuilder = $valueBuilder;
18: }
19:
20: public function addFields($args)
21: {
22: $this->addValuesToArray('fields', $args, true);
23: }
24:
25: public function setLimit($limit)
26: {
27: $this->assert(is_numeric($limit), "Limit must be a number");
28: $this->setValue('limit', $limit);
29: }
30:
31: public function setOffset($offset)
32: {
33: $this->assert(is_numeric($offset), "Offset must be a number");
34: $this->setValue('offset', $offset);
35: }
36:
37: public function addOrderAscendingBy($field)
38: {
39: $this->addToArray('orderBy', $this->valueBuilder->orderBy($field, 'asc'));
40: }
41:
42: public function addOrderDescendingBy($field)
43: {
44: $this->addToArray('orderBy', $this->valueBuilder->orderBy($field, 'desc'));
45: }
46:
47: public function addSet($args)
48: {
49: $this->addKeyValuesToArray('set', $args, true);
50: }
51:
52: public function setData($data)
53: {
54: $this->assert(is_array($data), "Data must be an array");
55: $this->setValue('data', $data);
56: }
57:
58: public function clearValue($name)
59: {
60: $this->values[$name] = null;
61: }
62:
63: public function getValue($name)
64: {
65: if(!array_key_exists($name, $this->values))
66:
67: return null;
68:
69: return $this->values[$name];
70: }
71:
72: protected function setValue($name, $value)
73: {
74: $this->values[$name] = $value;
75: }
76:
77: public function clearArray($name)
78: {
79: if(array_key_exists($name, $this->arrays))
80: unset($this->arrays[$name]);
81: }
82:
83: public function getArray($name)
84: {
85: if(!array_key_exists($name, $this->arrays))
86:
87: return array();
88:
89: return $this->arrays[$name];
90: }
91:
92: protected function ensureArray($name)
93: {
94: if(!array_key_exists($name, $this->arrays))
95: $this->arrays[$name] = array();
96: }
97:
98: protected function addToArray($name, $value)
99: {
100: $this->ensureArray($name);
101: $this->arrays[$name][]= $value;
102: }
103:
104: protected function addValuesToArray($name, $args, $unique = false)
105: {
106: $values = $args[0];
107: if (!is_array($values)) {
108: $values = array($values);
109: }
110:
111: $this->ensureArray($name);
112: foreach($values as $value)
113: if(!$unique || !in_array($value, $this->arrays[$name]))
114: $this->arrays[$name][]= $value;
115: }
116:
117: protected function addKeyValuesToArray($name, $args, $requireKeys = false, $firstParameterIsKey = true, $assertIsNumeric = false)
118: {
119: $array = $args[0];
120:
121: if (!is_array($array)) {
122: $count = count($args);
123: if ($count === 1) {
124: $this->assert(!$requireKeys, "Either an array, a key value pair or a single value may be passed.");
125: $array = array($array);
126: } else {
127: $this->assert($count === 2, "Only an array of keys and values or a single key value pair may be passed.");
128:
129: if ($firstParameterIsKey) {
130: $array = array($array => $args[1]);
131: } else {
132: $array = array($args[1] => $array);
133: }
134: }
135: }
136:
137: $this->ensureArray($name);
138: foreach ($array as $key => $value) {
139: if($assertIsNumeric)
140: $this->assert(is_numeric($value), "Value must be a number");
141: if (!is_string($key)) {
142: $this->assert(!$requireKeys, "A key must be specified.");
143: $this->arrays[$name][]= $value;
144: } else {
145: $this->arrays[$name][$key]= $value;
146: }
147: }
148: }
149:
150: public function conditionContainer($name = null)
151: {
152: if ($name === null) {
153: if($this->defaultContainer !== null) {
154: return $this->defaultContainer;
155: }else{
156: $name = 'where';
157: }
158: }
159:
160: if (!array_key_exists($name, $this->conditionContainers))
161: $this->conditionContainers[$name] = $this->conditions->container();
162: $this->defaultContainer = $this->conditionContainers[$name];
163:
164: return $this->defaultContainer;
165: }
166:
167: public function getConditions($name)
168: {
169: if (!isset($this->conditionContainers[$name]))
170: return array();
171:
172: return $this->conditionContainers[$name]->getConditions();
173: }
174:
175: public function addCondition($logic, $negate, $condition, $containerName = null)
176: {
177: $this->conditionContainer($containerName)->addCondition($logic, $negate, $condition);
178: }
179:
180: public function buildCondition($logic, $negate, $args, $containerName = null)
181: {
182: $this->conditionContainer($containerName)->buildCondition($logic, $negate, $args);
183: }
184:
185: public function addOperatorCondition($logic, $negate, $field, $operator, $values, $containerName = null)
186: {
187: $this->conditionContainer($containerName)->addOperatorCondition($logic, $negate, $field, $operator, $values);
188: }
189:
190: public function startConditionGroup($logic = 'and', $negate = false, $containerName = null)
191: {
192: $this->conditionContainer($containerName)->startConditionGroup($logic, $negate);
193: }
194:
195: public function endConditionGroup($containerName = null)
196: {
197: $this->conditionContainer($containerName)->endGroup();
198: }
199:
200: public function addPlaceholder($logic = 'and', $negate = false, $allowEmpty = true, $containerName = null)
201: {
202: return $this->conditionContainer($containerName)->addPlaceholder($logic, $negate, $allowEmpty);
203: }
204:
205: public function assert($condition, $exceptionMessage)
206: {
207: if(!$condition)
208: throw new \PHPixie\Database\Exception\Builder($exceptionMessage);
209: }
210:
211: }
212: