OqlSelectPropertiesParser.class.php

Go to the documentation of this file.
00001 <?php
00002 /****************************************************************************
00003  *   Copyright (C) 2009 by Vladlen Y. Koshelev                              *
00004  *                                                                          *
00005  *   This program is free software; you can redistribute it and/or modify   *
00006  *   it under the terms of the GNU Lesser General Public License as         *
00007  *   published by the Free Software Foundation; either version 3 of the     *
00008  *   License, or (at your option) any later version.                        *
00009  *                                                                          *
00010  ****************************************************************************/
00011 
00012     final class OqlSelectPropertiesParser extends OqlParser
00013     {
00014         // class map
00015         const SUM_PROJECTION            = 'sum';
00016         const AVG_PROJECTION            = 'avg';
00017         const MIN_PROJECTION            = 'min';
00018         const MAX_PROJECTION            = 'max';
00019         const COUNT_PROJECTION          = 'count';
00020         const DISTINCT_COUNT_PROJECTION = 1;
00021         const PROPERTY_PROJECTION       = 2;
00022         
00023         private static $classMap = array(
00024             self::SUM_PROJECTION            => 'SumProjection',
00025             self::AVG_PROJECTION            => 'AverageNumberProjection',
00026             self::MIN_PROJECTION            => 'MinimalNumberProjection',
00027             self::MAX_PROJECTION            => 'MaximalNumberProjection',
00028             self::COUNT_PROJECTION          => 'RowCountProjection',
00029             self::DISTINCT_COUNT_PROJECTION => 'DistinctCountProjection',
00030             self::PROPERTY_PROJECTION       => 'PropertyProjection'
00031         );
00032         
00036         public static function create()
00037         {
00038             return new self;
00039         }
00040         
00044         protected function makeOqlObject()
00045         {
00046             return OqlSelectPropertiesClause::create();
00047         }
00048         
00049         protected function handleState()
00050         {
00051             if ($this->state == self::INITIAL_STATE) {
00052                 $list = $this->getCommaSeparatedList(
00053                     array($this, 'getArgumentExpression'),
00054                     'expecting expression or aggregate function call'
00055                 );
00056                 
00057                 foreach ($list as $argument)
00058                     $this->oqlObject->add($argument);
00059             }
00060             
00061             return self::FINAL_STATE;
00062         }
00063         
00067         protected function getArgumentExpression()
00068         {
00069             $token = $this->tokenizer->peek();
00070             
00071             // aggregate function
00072             if ($this->checkToken($token, OqlToken::AGGREGATE_FUNCTION)) {
00073                 $this->tokenizer->next();
00074                 
00075                 if ($this->openParentheses(false)) {
00076                     
00077                     if (($functionName = $this->getTokenValue($token)) == 'count') {
00078                         if ($this->checkKeyword($this->tokenizer->peek(), 'distinct')) {
00079                             $this->tokenizer->next();
00080                             $functionName = self::DISTINCT_COUNT_PROJECTION;
00081                         }
00082                         
00083                         $expression = $this->getLogicExpression();
00084                         
00085                     } else {
00086                         $expression = $this->getArithmeticExpression();
00087                     }
00088                     
00089                     $this->closeParentheses(true, "in function call: {$this->getTokenValue($token)}");
00090                     
00091                     return $this->makeQueryExpression(
00092                         self::$classMap[$functionName],
00093                         $expression,
00094                         $this->getAlias()
00095                     );
00096                     
00097                 } else
00098                     $this->tokenizer->back();
00099             }
00100             
00101             // property
00102             if ($this->checkKeyword($token, 'distinct')) {
00103                 $token = $this->tokenizer->next();
00104                 $this->oqlObject->setDistinct(true);
00105             }
00106             
00107             return $this->makeQueryExpression(
00108                 self::$classMap[self::PROPERTY_PROJECTION],
00109                 $this->getLogicExpression(),
00110                 $this->getAlias()
00111             );
00112         }
00113         
00117         private function getAlias()
00118         {
00119             if ($this->checkKeyword($this->tokenizer->peek(), 'as')) {
00120                 $this->tokenizer->next();
00121                 
00122                 if (
00123                     !($alias = $this->tokenizer->next())
00124                     || !$this->checkIdentifier($alias)
00125                 ) {
00126                     $this->error(
00127                         'expecting alias name:',
00128                         $this->getTokenValue($alias, true)
00129                     );
00130                 }
00131                 
00132                 return $alias;
00133             }
00134             
00135             return null;
00136         }
00137     }
00138 ?>