1: <?php
2:
3: namespace PHPixie\Database\Type\SQL\Parser;
4:
5: abstract class Operator extends \PHPixie\Database\Parser\Operator
6: {
7: protected $database;
8: protected $fragmentParser;
9:
10: protected $operators = array(
11: 'compare' => array('<', '<=', '=', '<>', '!=', '>=', '>', '<*', '<=*', '=*', '<>*', '!=*', '>=*', '>*'),
12: 'pattern' => array('like', 'not like', 'regexp', 'not regexp'),
13: 'in' => array('in', 'not in'),
14: 'between' => array('between', 'not between'),
15: );
16:
17: public function __construct($database, $fragmentParser)
18: {
19: $this->database = $database;
20: $this->fragmentParser = $fragmentParser;
21: parent::__construct();
22: }
23:
24: protected function prefix($field, $operator)
25: {
26: $expr = $this->database->sqlExpression();
27: $this->fragmentParser->appendColumn($field, $expr);
28: $expr->sql .= ' '.strtoupper($operator).' ';
29:
30: return $expr;
31: }
32:
33: protected function singleValue($values, $operator)
34: {
35: if(count($values) !== 1)
36: throw new \PHPixie\Database\Exception\Parser(strtoupper($operator)." operator requires a single parameter");
37:
38: return $values[0];
39: }
40:
41: protected function parseCompare($field, $operator, $values)
42: {
43: $isColumn = false;
44:
45: if (substr($operator, -1, 1) === '*') {
46: $operator = substr($operator, 0, -1);
47: $isColumn = true;
48: }
49:
50: $value = $this->singleValue($values, $operator);
51:
52: if ($operator === '!=')
53: $operator = '<>';
54:
55: if ($value === null) {
56: if ($isColumn)
57: throw new \PHPixie\Database\Exception\Parser("A column comparison operator '{$operator}*' was given a NULL instead of column");
58:
59: if ($operator === '=') {
60: $operator = 'is';
61: } elseif ($operator === '<>') {
62: $operator = 'is not';
63: }
64: }
65:
66: $expr = $this->prefix($field, $operator);
67:
68: if ($value === null) {
69: $expr->sql.= "NULL";
70: } elseif ($isColumn) {
71: $this->fragmentParser->appendColumn($value, $expr);
72: } else {
73: $this->fragmentParser->appendValue($value, $expr);
74: }
75:
76: return $expr;
77: }
78:
79: protected function parseBetween($field, $operator, $range)
80: {
81: if (count($range) !== 2)
82: throw new \PHPixie\Database\Exception\Parser(strtoupper($operator)." operator parameter requires two parameters");
83:
84: $expr = $this->prefix($field, $operator);
85: $this->fragmentParser->appendValue($range[0], $expr);
86: $expr->sql.= " AND ";
87: $this->fragmentParser->appendValue($range[1], $expr);
88:
89: return $expr;
90: }
91:
92: protected function parsePattern($field, $operator, $values)
93: {
94: $value = $this->singleValue($values, $operator);
95:
96: $expr = $this->prefix($field, $operator);
97: $this->fragmentParser->appendValue($value, $expr);
98:
99: return $expr;
100: }
101:
102: protected function parseIn($field, $operator, $values)
103: {
104: $value = $this->singleValue($values, $operator);
105:
106: if(is_array($value) && count($value) === 0) {
107: $condition = $operator === 'in' ? 'FALSE' : 'TRUE';
108: return $this->database->sqlExpression($condition);
109: }
110:
111: $expr = $this->prefix($field, $operator);
112: if (is_array($value)) {
113: $listSql = str_pad('', count($value) * 3 - 2, '?, ');
114: $expr->sql.= "($listSql)";
115: $expr->params = array_merge($expr->params, $value);
116: } elseif ($value instanceof \PHPixie\Database\Type\SQL\Query) {
117: $subquery = $value->parse();
118: $expr->sql.= "( ";
119: $expr->append($subquery);
120: $expr->sql.= " )";
121: } elseif ($value instanceof \PHPixie\Database\Type\SQL\Expression) {
122: $expr->sql.= "( ";
123: $expr->append($value);
124: $expr->sql.= " )";
125: } else {
126: throw new \PHPixie\Database\Exception\Parser(strtoupper($operator)." operator parameter must be either an array, a query or an expression");
127: }
128:
129: return $expr;
130: }
131: }
132: