/** * @access public * * @param bool $subSelect * * @return Core\Datamodel\Dataset */ public function parseSelect($subSelect = false) { $tree = new Core\Datamodel\Dataset(); $tree->_mode = Core\Datamodel\Dataset::MODE_GET; $this->getTok(); if ($this->token == 'distinct') { $tree->uniquerecords = true; $this->getTok(); } // SELECT columns $selects = []; while (1) { $exp = $this->parseCondition()['args'][0]; if(isset($exp['name'])){ $this->raiseError('Datasets do not support functions as SELECT parameters!'); } if(isset($exp['value'])){ $selects[] = $exp['value']; } elseif(isset($exp['column'])){ $selects[] = $exp['column']; } else{ $this->raiseError('Unknown SELECT object'); } if ($this->token != ',') { break; } $this->getTok(); } $tree->select($selects); // FROM if ($this->token != 'from') { return $tree; } $this->getTok(); $table = $this->parseFrom(); if(sizeof($table['table_references']['table_factors']) != 1){ $this->raiseError('Datasets only support one table at a time!'); } $tree->table($table['table_references']['table_factors'][0]['table']); // WHERE // GROUP BY // HAVING // ORDER BY // LIMIT // UNION while ($this->token != ';' && ! is_null($this->token) && (!$subSelect || $this->token != ')') && $this->token != ')') { switch ($this->token) { case 'where': $this->getTok(); $clause = $this->parseWhereCondition(); if (false === $clause) { return $clause; } $tree->_where = $clause; break; case 'order': $this->getTok(); if ($this->token != 'by') { $this->raiseError('Expected "by"'); } $this->getTok(); while ($this->token == 'ident') { $arg = $this->lexer->tokText; $this->getTok(); if ($this->token == '.') { $this->getTok(); if ($this->token == 'ident') { $arg .= '.'.$this->lexer->tokText; } else { $this->raiseError('Expected a column name'); } } else { $this->lexer->pushBack(); } $col = $arg; //$col = $this->lexer->tokText; $this->getTok(); if (isset($this->synonyms[$this->token])) { $order = $this->synonyms[$this->token]; if (($order != 'asc') && ($order != 'desc')) { $this->raiseError('Unexpected token'); } $this->getTok(); } else { $order = 'asc'; } if ($this->token == ',') { $this->getTok(); } $tree->order($col . ' ' . $order); } break; case 'limit': $this->getTok(); if ($this->token != 'int_val') { $this->raiseError('Expected an integer value'); } $length = $this->lexer->tokText; $start = 0; $this->getTok(); if ($this->token == ',') { $this->getTok(); if ($this->token != 'int_val') { $this->raiseError('Expected an integer value'); } $start = $length; $length = $this->lexer->tokText; $this->getTok(); } $tree->limit($start . ' ' . $length); break; case 'group': $this->getTok(); if ($this->token != 'by') { $this->raiseError('Expected "by"'); } $this->getTok(); while ($this->token == 'ident') { $arg = $this->lexer->tokText; $this->getTok(); if ($this->token == '.') { $this->getTok(); if ($this->token == 'ident') { $arg .= '.'.$this->lexer->tokText; } else { $this->raiseError('Expected a column name'); } } else { $this->lexer->pushBack(); } $col = $arg; //$col = $this->lexer->tokText; $this->getTok(); if ($this->token == ',') { $this->getTok(); } $this->raiseError('@TODO group by statements not supported yet'); $tree['group_by'][] = $col; } break; default: $this->raiseError('Unexpected clause'); } } return $tree; }