1: <?php
2:
3: namespace Alchemy\core\query;
4: use Alchemy\core\Element;
5: use Alchemy\util\Monad;
6:
7:
8: 9: 10:
11: class Query extends Element implements IQuery {
12: protected $columns = array();
13: protected $joins = array();
14: protected $where;
15: protected $limit;
16: protected $offset;
17: protected $table;
18:
19:
20: public function __construct($type, TableRef $table) {
21: parent::__construct($type);
22: $this->table = $table;
23: }
24:
25:
26: public function __set($name, $value) {
27: if (!($value instanceof Element) || !$value->getTag('expr.value')) {
28: $schema = $this->table->schema();
29: $value = $schema->hasColumn($name)
30: ? $schema->getColumn($name)->encode($value)
31: : new Scalar($value);
32: }
33:
34: $this->columns[$name] = $value;
35: }
36:
37:
38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
48: public function columns() {
49: if (func_num_args() == 0) {
50: return $this->columns;
51: }
52:
53: $columns = func_get_args();
54: $columns = (count($columns) == 1 && is_array($columns[0])) ? $columns[0] : $columns;
55:
56: foreach ($columns as $name => $column) {
57: if (is_integer($name) && is_array($column)) {
58: $name = $column[0];
59: $column = $column[1];
60: }
61:
62: $name = is_string($name) ? $name : $column->name();
63: $this->__set($name, $column);
64: }
65:
66: return $this;
67: }
68:
69:
70: 71: 72: 73: 74:
75: public function parameters() {
76: $params = $this->where ? $this->where->parameters() : array();
77:
78: if ($this->limit) {
79: $params[] = $this->limit;
80: }
81:
82: if ($this->offset) {
83: $params[] = $this->offset;
84: }
85:
86: foreach ($this->columns as $column) {
87: if ($column instanceof Scalar) {
88: $params[] = $column;
89: }
90: }
91:
92: foreach ($this->joins as $join) {
93: $params = array_merge($params, $join->parameters());
94: }
95:
96: return $params;
97: }
98:
99:
100: 101: 102: 103: 104: 105: 106: 107:
108: public function join($table, Predicate $on = null, $direction = null, $type = null) {
109: $direction = $direction ?: Join::LEFT;
110: $type = $type ?: Join::INNER;
111:
112: $this->joins[] = new Join($direction, $type, $table, $on);
113: return $this;
114: }
115:
116:
117: public function joins() {
118: return $this->joins;
119: }
120:
121:
122: 123: 124: 125: 126: 127: 128:
129: public function outerJoin($table, Predicate $on, $direction = null) {
130: return $this->join($table, $on, $direction, Join::OUTER);
131: }
132:
133:
134: 135: 136: 137: 138:
139: public function table() {
140: return $this->table;
141: }
142:
143:
144: 145: 146: 147: 148: 149: 150:
151: public function where($expr = false) {
152: if ($expr === false) {
153: return $this->where;
154: }
155:
156: $this->where = is_null($expr) ? null : Predicate::ALL(func_get_args());
157: return $this;
158: }
159:
160:
161: 162: 163: 164: 165:
166: public function limit($limit = false) {
167: if ($limit === false) {
168: return $this->limit;
169: }
170:
171: $this->limit = is_null($limit) ? null : new Scalar($limit);
172: return $this;
173: }
174:
175:
176: 177: 178: 179: 180:
181: public function offset($offset = false) {
182: if ($offset === false) {
183: return $this->offset;
184: }
185:
186: $this->offset = is_null($offset) ? null : new Scalar($offset);
187: return $this;
188: }
189: }
190: